From 62747accdb2b164b9f32839ed61b57f848390804 Mon Sep 17 00:00:00 2001 From: Ruslan Ibragimov Date: Wed, 8 Jan 2025 11:18:36 +0300 Subject: [PATCH] Awesome Kotlin: 2025 --- .editorconfig | 2 +- .env.example | 31 +- .github/contributing.md | 16 +- .github/issue_template.md | 2 +- .github/pull_request_template.md | 4 - .github/workflows/build.yml | 2 + .gitignore | 3 - .run/Awesome Kotlin 1.0.run.xml | 10 - Backlog.txt | 9 + README.md | 4 +- .../src/main/kotlin/Generate.kt | 2 +- app-backend/Dockerfile | 4 - app-backend/api-resources.http | 14 + app-backend/api.http | 21 +- app-backend/build.gradle.kts | 29 +- app-backend/docker-compose.dev.yml | 2 +- app-backend/src/main/kotlin/Application.kt | 140 +- .../src/main/kotlin/ApplicationModule.kt | 43 + app-backend/src/main/kotlin/ConfigModule.kt | 22 - app-backend/src/main/kotlin/FlywayModule.kt | 13 - .../src/main/kotlin/HttpClientModule.kt | 23 - .../src/main/kotlin/LifecycleModule.kt | 16 - app-backend/src/main/kotlin/MetricsModule.kt | 9 - app-backend/src/main/kotlin/ServerModule.kt | 103 - app-backend/src/main/kotlin/XmlModule.kt | 11 - app-backend/src/main/kotlin/YamlModule.kt | 8 - app-backend/src/main/kotlin/config/dotenv.kt | 37 - .../src/main/kotlin/infra/HttpClientModule.kt | 31 + .../main/kotlin/infra/cache/CacheBuilder.kt | 10 + .../main/kotlin/infra/cache/LoadingCache.kt | 44 + .../kotlin/infra/cache/SimpleLoadingCache.kt | 50 + .../main/kotlin/infra/config/ConfigModule.kt | 44 + .../src/main/kotlin/infra/db/FlywayModule.kt | 16 + .../main/kotlin/{ => infra/db}/JdbcModule.kt | 38 +- .../main/kotlin/{ => infra/db}/JooqModule.kt | 9 +- .../kotlin/infra/file_watcher/FileMonitor.kt | 49 + .../infra/file_watcher/FileMonitorModule.kt | 10 + .../src/main/kotlin/infra/ktor/KtorFeature.kt | 7 + .../kotlin/infra/ktor/KtorFeaturesModule.kt | 66 + .../src/main/kotlin/infra/ktor/KtorRoute.kt | 16 + .../ktor/features/AuthenticationFeature.kt | 53 + .../infra/ktor/features/CachingFeature.kt | 42 + .../infra/ktor/features/CallLoggingFeature.kt | 16 + .../features/ContentNegotiationFeature.kt | 14 + .../infra/ktor/features/MetricsFeature.kt | 19 + .../infra/ktor/features/ResourcesFeature.kt | 11 + .../infra/ktor/features/StatusPageFeature.kt | 39 + .../infra/ktor/features/WebSocketsFeature.kt | 41 + .../infra/lifecycle/AutoClosableModule.kt | 36 + .../{ => infra}/lifecycle/GracefulShutdown.kt | 2 +- .../kotlin/infra/lifecycle/LifecycleModule.kt | 25 + .../{ => infra}/lifecycle/ShutdownManager.kt | 8 +- .../kotlin/infra/metrics/MetricsModule.kt | 45 + .../main/kotlin/infra/metrics/MetricsRoute.kt | 22 + .../serialization/TimeSerializers.kt | 2 +- .../kotlin/infra/serialization/XmlModule.kt | 11 + .../kotlin/infra/serialization/YamlModule.kt | 11 + .../kotlin/{ => infra}/utils/collections.kt | 2 +- .../main/kotlin/jooq/main/DefaultCatalog.kt | 2 +- .../src/main/kotlin/jooq/main/Public.kt | 9 +- .../src/main/kotlin/jooq/main/keys/Keys.kt | 3 + .../main/kotlin/jooq/main/tables/Article.kt | 34 +- .../main/kotlin/jooq/main/tables/Comment.kt | 32 +- .../kotlin/jooq/main/tables/GithubAuth.kt | 207 + .../main/kotlin/jooq/main/tables/Kotliner.kt | 64 +- .../main/kotlin/jooq/main/tables/KugEvent.kt | 32 +- .../kotlin/jooq/main/tables/VideoLibrary.kt | 32 +- .../kotlin/jooq/main/tables/VideoSpeaker.kt | 32 +- .../jooq/main/tables/daos/GithubAuthDao.kt | 135 + .../jooq/main/tables/pojos/GithubAuth.kt | 125 + .../main/tables/records/GithubAuthRecord.kt | 97 + .../jooq/main/tables/references/Tables.kt | 6 + app-backend/src/main/kotlin/ktor/KtorRoute.kt | 7 - .../src/main/kotlin/ktor/plugins/HTTP.kt | 112 - .../main/kotlin/ktor/plugins/Monitoring.kt | 31 - .../src/main/kotlin/ktor/plugins/Sockets.kt | 39 - .../src/main/kotlin/model/KotlinPlatform.kt | 32 - .../src/main/kotlin/model/KotlinVersion.kt | 3 - app-backend/src/main/kotlin/model/Language.kt | 6 - .../main/kotlin/server/KtorRoutesModule.kt | 64 + .../main/kotlin/server/KtorServerModule.kt | 85 + .../kotlin/usecases/articles/ArticleSource.kt | 79 + .../usecases/articles/ArticlesModule.kt | 50 + .../usecases/articles}/ArticlesProcessor.kt | 26 +- .../usecases/articles/MarkdownRenderer.kt | 14 + .../usecases/articles}/PagesGenerator.kt | 98 +- .../github/AuthGithubRedirectRoute.kt | 4 +- .../usecases/github/GithubAccessToken.kt | 7 +- .../kotlin/usecases/github/GithubAuthRoute.kt | 14 +- .../kotlin/usecases/github/GithubModule.kt | 32 +- .../usecases/github_trending/GithubConfig.kt | 8 + .../GithubTrendingLinkSource.kt | 54 +- .../GithubTrendingLinkSourceModule.kt | 18 + .../usecases/healthcheck/HealthCheckRoute.kt | 17 + .../usecases/healthcheck/HealthcheckModule.kt | 10 + .../main/kotlin/usecases/kug/GetKugsRoute.kt | 4 +- .../src/main/kotlin/usecases/kug/KugDao.kt | 2 +- .../src/main/kotlin/usecases/kug/KugModule.kt | 28 +- .../kotlin/usecases/kug/UpdateKugsRoute.kt | 4 +- .../usecases/links/CategoryProcessor.kt | 23 + .../kotlin/usecases/links/LinkSourceModel.kt | 43 + .../src/main/kotlin/usecases/links/Links.kt | 175 - .../kotlin/usecases/links/LinksChecker.kt | 25 + .../kotlin/usecases/links/LinksDtoSource.kt | 11 + .../main/kotlin/usecases/links/LinksModule.kt | 83 + .../kotlin/usecases/links}/LinksProcessor.kt | 116 +- .../main/kotlin/usecases/links/LinksRoute.kt | 33 + .../main/kotlin/usecases/links/LinksSource.kt | 37 + .../kotlin/usecases/links/LinksV1Model.kt | 110 + .../src/main/kotlin/usecases/ping/Ping.kt | 19 - .../main/kotlin/usecases/ping/PingModule.kt | 9 - .../usecases/readme}/ReadmeGenerator.kt | 6 +- .../kotlin/usecases/readme/ReadmeModule.kt | 20 + .../kotlin/usecases/readme/ReadmeRoute.kt | 20 + .../usecases/reload/LiveReloadModule.kt | 20 + .../usecases/reload/LiveReloadService.kt | 30 + .../usecases/reload/NotificationChannel.kt | 36 + .../reload/NotificationChannelModule.kt | 10 + .../usecases/robots_txt/RobotsTxtModule.kt | 15 + .../usecases/robots_txt/RobotsTxtRoute.kt | 36 + .../main/kotlin/usecases/rss}/RssGenerator.kt | 21 +- .../src/main/kotlin/usecases/rss/RssModule.kt | 27 + .../src/main/kotlin/usecases/rss/RssRoute.kt | 40 + .../kotlin/usecases/signup/GenerateJwt.kt | 4 +- .../main/kotlin/usecases/signup/JwtModule.kt | 19 +- .../kotlin/usecases/signup/KotlinerDao.kt | 4 +- .../src/main/kotlin/usecases/signup/Login.kt | 31 +- .../main/kotlin/usecases/signup/Register.kt | 23 +- .../main/kotlin/usecases/sitemap}/Sitemap.kt | 2 +- .../usecases/sitemap/SitemapGenerator.kt | 43 + .../kotlin/usecases/sitemap/SitemapModule.kt | 24 + .../kotlin/usecases/sitemap/SitemapRoute.kt | 23 + .../kotlin/usecases/stars_job/StarsJob.kt | 53 + .../usecases/version/KotlinVersionFetcher.kt | 55 +- .../usecases/version/KotlinVersionModule.kt | 23 +- .../usecases/version/KotlinVersionRoute.kt | 15 + .../kotlin/usecases/version/MavenModel.kt | 38 + .../kotlin/usecases/web/DeploymentContext.kt | 15 + .../usecases/web/WebApplicationContext.kt | 10 + .../src/main/kotlin/usecases/web/WebModule.kt | 25 + .../src/main/kotlin/utils/closeable.kt | 10 - app-backend/src/main/kotlin/utils/logging.kt | 18 - .../src/main/resources/application.conf | 36 +- .../src/main/resources/data/articles.json | 1 + .../src/main/resources/data/links.json | 1 + .../infra/db/migration/main/V1__auth.sql | 11 + .../db/migration/main/V20221213__init.sql | 0 .../src/main/resources/links/Android.json | 2760 ------ .../src/main/resources/links/Archive.json | 264 - .../src/main/resources/links/JavaScript.json | 390 - .../src/main/resources/links/Libraries.json | 7510 ----------------- .../src/main/resources/links/Links.json | 1071 --- .../src/main/resources/links/Native.json | 119 - .../src/main/resources/links/Projects.json | 1 - .../src/main/resources/links/UserGroups.json | 3537 -------- app-backend/src/test/kotlin/di/BeanMockk.kt | 13 - .../src/test/kotlin/types/IntegrationTest.kt | 10 + app-backend/src/test/kotlin/types/UnitTest.kt | 10 + .../usecases/kug/KugDownloadServiceTest.kt | 24 +- .../usecases/robots_txt/RobotsTxtRouteTest.kt | 49 + .../MavenCentralKotlinVersionFetcherTest.kt | 20 + app-frontend/.pnp.cjs | 5114 +++++------ ...frame-npm-7.15.8-c1e84dfd13-d75950f0e0.zip | Bin 3937 -> 0 bytes ...ifier-npm-7.15.7-a8f354e738-50aad8bc14.zip | Bin 9286 -> 0 bytes ...light-npm-7.14.5-4a18106cbc-4e4b22fb88.zip | Bin 3407 -> 0 bytes ...misify-npm-1.1.2-2343f94380-d05081e088.zip | Bin 2198 -> 0 bytes ...-cliui-npm-8.0.2-f4364666d5-e9ed5fd27c.zip | Bin 0 -> 10590 bytes ...nipass-npm-4.0.1-677026e841-4412e9e671.zip | Bin 0 -> 24207 bytes ...hemas-npm-29.6.3-292730e442-910040425f.zip | Bin 0 -> 3367 bytes ...types-npm-29.6.3-a584ca999d-f74bf512fd.zip | Bin 0 -> 10095 bytes ...apping-npm-0.3.2-c64eeb4a4e-7ba0070be1.zip | Bin 27227 -> 0 bytes ...apping-npm-0.3.8-647be6e286-9d3a56ab36.zip | Bin 0 -> 23511 bytes ...ve-uri-npm-3.1.0-6ff2351e61-320ceb37af.zip | Bin 18350 -> 0 bytes ...ve-uri-npm-3.1.1-aa2de3f210-64d59df8ae.zip | Bin 18345 -> 0 bytes ...ve-uri-npm-3.1.2-5bc4245992-97106439d7.zip | Bin 0 -> 17946 bytes ...-array-npm-1.1.2-45b82d7fb6-69a84d5980.zip | Bin 8860 -> 0 bytes ...-array-npm-1.2.1-2312928209-832e513a85.zip | Bin 0 -> 8928 bytes ...ce-map-npm-0.3.2-6fd1f37b22-1aaa42075b.zip | Bin 56381 -> 0 bytes ...ce-map-npm-0.3.5-9f964eaf44-73838ac432.zip | Bin 56399 -> 0 bytes ...ce-map-npm-0.3.6-fe0849eb05-0a9aca9320.zip | Bin 0 -> 43407 bytes ...codec-npm-1.4.14-f5f0630788-26e768fae6.zip | Bin 13744 -> 0 bytes ...codec-npm-1.4.15-a055fb62cf-89960ac087.zip | Bin 15065 -> 0 bytes ...-codec-npm-1.5.0-dfd9126d71-4ed6123217.zip | Bin 0 -> 27849 bytes ...pping-npm-0.3.17-57578fd48c-790d439c9b.zip | Bin 45471 -> 0 bytes ...pping-npm-0.3.22-0baba2f798-48d3e3db00.zip | Bin 45413 -> 0 bytes ...pping-npm-0.3.25-c076fd2279-dced32160a.zip | Bin 0 -> 46679 bytes ...-codec-npm-2.0.4-dd4d657af8-3c7ffb0afb.zip | Bin 7881 -> 0 bytes ...-agent-npm-3.0.0-169e79294f-775c9a7eb1.zip | Bin 0 -> 8469 bytes ...cli-fs-npm-1.0.0-92194475f3-3f93c1d9a8.zip | Bin 14039 -> 0 bytes ...cli-fs-npm-4.0.0-1d9cc8a27b-405c4490e1.zip | Bin 0 -> 12586 bytes ...e-file-npm-1.1.2-4f6c7b3354-c96381d4a3.zip | Bin 3850 -> 0 bytes ...r-darwin-arm64-npm-2.5.0-4eab519184-10.zip | Bin 0 -> 127724 bytes ...atcher-npm-2.5.0-f36bd41c3b-1e28b1aa9a.zip | Bin 0 -> 52137 bytes ...eargs-npm-0.11.0-cd2a3fe948-115e8ceeec.zip | Bin 0 -> 28004 bytes ...pebox-npm-0.27.8-23e206d653-297f95ff77.zip | Bin 0 -> 88455 bytes ...treams-npm-1.0.0-2ae6684f8f-453c2a2816.zip | Bin 3427 -> 0 bytes ...treams-npm-2.3.0-5d49fcd96d-798bcb53cd.zip | Bin 0 -> 5206 bytes ...e-once-npm-1.1.2-0517220057-e1fb1bbbc1.zip | Bin 2809 -> 0 bytes ...nd-sax-npm-0.2.0-9f763d0295-7379713eca.zip | Bin 0 -> 14512 bytes ...arser-npm-1.19.2-f845b7b538-e17840c7d7.zip | Bin 4092 -> 0 bytes ...njour-npm-3.5.13-6614f112a1-e827570e09.zip | Bin 3196 -> 0 bytes ...llback-npm-1.5.4-c8b583432c-e1dee43b85.zip | Bin 3346 -> 0 bytes ...nnect-npm-3.4.35-7337eee0a3-fe81351470.zip | Bin 3487 -> 0 bytes ...cookie-npm-0.6.0-1f4c3f48f0-b883348d5b.zip | Bin 4367 -> 0 bytes ...ress-npm-4.17.14-076e1b4711-293e53a757.zip | Bin 3770 -> 0 bytes ...ress-npm-4.17.21-be92a0245e-7a6d26cf6f.zip | Bin 3596 -> 0 bytes ...core-npm-4.17.31-846873f446-020210f32d.zip | Bin 12962 -> 0 bytes ...core-npm-4.17.43-9cbdf8ef01-9079e13747.zip | Bin 13366 -> 0 bytes ...terser-npm-6.0.0-3667095d04-6680492f2a.zip | Bin 4359 -> 0 bytes ...terser-npm-6.1.0-707ea07fcb-06bb3e1e8e.zip | Bin 0 -> 4398 bytes ...errors-npm-2.0.4-8b39ca5d7c-1f3d7c3b32.zip | Bin 3347 -> 0 bytes ...proxy-npm-1.17.9-fa2f5ce316-48075c535a.zip | Bin 4851 -> 0 bytes ...verage-npm-2.0.6-2ea31fda9c-3feac423fd.zip | Bin 0 -> 3111 bytes ...report-npm-3.0.3-a5c0ef4b88-b91e9b60f8.zip | Bin 0 -> 4070 bytes ...eports-npm-3.0.4-1afa69db29-93eb188357.zip | Bin 0 -> 3632 bytes ...chema-npm-7.0.11-79462ae5ca-e50864a93f.zip | Bin 7176 -> 0 bytes ...schema-npm-7.0.9-361918cff3-7ceb41e396.zip | Bin 7176 -> 0 bytes ...s-mime-npm-1.3.5-48d28990db-e29a5f9c47.zip | Bin 3214 -> 0 bytes ...s-mime-npm-3.0.1-dec03536dc-4040fac73f.zip | Bin 3128 -> 0 bytes ...forge-npm-1.3.11-132541fb70-670c9b377c.zip | Bin 13386 -> 0 bytes ...node-npm-15.14.9-739a59edff-5c9cc5346c.zip | Bin 139022 -> 0 bytes ...pes-qs-npm-6.9.7-4a3e6ca0d0-7fd6f9c250.zip | Bin 3396 -> 0 bytes ...parser-npm-1.2.4-23d797fbde-b7c0dfd508.zip | Bin 3450 -> 0 bytes ...retry-npm-0.12.2-e1f0617c50-e567503571.zip | Bin 3922 -> 0 bytes ...-send-npm-0.17.4-9d7c55577f-28320a2aa1.zip | Bin 4429 -> 0 bytes ...-index-npm-1.9.4-957ae0ac38-72727c88d5.zip | Bin 3178 -> 0 bytes ...tatic-npm-1.15.0-ec80a4ac87-5f2f36a8f5.zip | Bin 4194 -> 0 bytes ...tatic-npm-1.15.5-b911ffc092-49aa21c367.zip | Bin 4124 -> 0 bytes ...ockjs-npm-0.3.36-e07c2960d5-b4b5381122.zip | Bin 3312 -> 0 bytes ...es-ws-npm-8.5.10-a877a38f71-9b414dc5e0.zip | Bin 6139 -> 0 bytes ...args-npm-17.0.33-1d6cca6a2e-16f6681bf4.zip | Bin 0 -> 16013 bytes ...arser-npm-21.0.3-1d265246a1-a794eb750e.zip | Bin 0 -> 4173 bytes ...abbrev-npm-1.1.1-3659247eab-2d88294118.zip | Bin 2939 -> 0 bytes ...abbrev-npm-2.0.0-0eb38a17e5-ca0a54e35b.zip | Bin 0 -> 3145 bytes ...ccepts-npm-1.3.7-0dc9de65aa-599aa3cc77.zip | Bin 6487 -> 0 bytes ...ccepts-npm-1.3.8-9a812371c9-67eaaa90e2.zip | Bin 6505 -> 0 bytes ...acorn-npm-8.10.0-2230c9e83e-522310c20f.zip | Bin 125646 -> 0 bytes .../acorn-npm-8.8.1-20e4aea981-c77a64b3b6.zip | Bin 120064 -> 0 bytes ...t-base-npm-6.0.2-428f325a93-21fb903e09.zip | Bin 13595 -> 0 bytes ...t-base-npm-7.1.3-b2c16e72fb-3db6d8d465.zip | Bin 0 -> 10828 bytes ...palive-npm-4.1.4-4d5b41b4c1-848634c4e1.zip | Bin 14356 -> 0 bytes ...-error-npm-3.1.0-415a406f4e-1101a33f21.zip | Bin 4089 -> 0 bytes .../ajv-npm-8.11.2-96b35a945e-6a68106196.zip | Bin 402830 -> 0 bytes ... ajv-npm-8.17.1-12ade7edc6-ee3c62162c.zip} | Bin 403399 -> 404220 bytes ...munity-npm-0.0.8-5eaef55f1b-08df369672.zip | Bin 8874 -> 0 bytes ...-regex-npm-2.1.1-ddd24d102b-190abd03e4.zip | Bin 3048 -> 0 bytes ...-regex-npm-6.1.0-abe011aae4-495834a53b.zip | Bin 0 -> 3772 bytes ...styles-npm-3.2.1-8cb8107983-d85ade01c1.zip | Bin 4630 -> 0 bytes ...styles-npm-6.2.1-d43647018c-70fdf883b7.zip | Bin 0 -> 7052 bytes ...ymatch-npm-3.1.2-1d5471acfa-985163db22.zip | Bin 4628 -> 0 bytes ...aproba-npm-1.2.0-34129f0778-48def77733.zip | Bin 4270 -> 0 bytes ...re-yet-npm-1.1.7-db9f39924e-5fc14ea29e.zip | Bin 7358 -> 0 bytes ...gparse-npm-2.0.1-faff7999e6-18640244e6.zip | Bin 41278 -> 0 bytes ...latten-npm-1.1.1-9d94ad5f1d-e13c9d2472.zip | Bin 2764 -> 0 bytes ...ixer-npm-10.4.20-dd5fd05d27-d3c4b562fc.zip | Bin 75800 -> 0 bytes .../batch-npm-0.6.1-70e2e81169-61f9934c73.zip | Bin 4709 -> 0 bytes ...nsions-npm-2.2.0-180c33fec7-ccd267956c.zip | Bin 3909 -> 0 bytes ...arser-npm-1.20.3-c7b184cd14-8723e3d7a6.zip | Bin 21563 -> 0 bytes ...ervice-npm-1.2.1-3b11acdfe6-8350d135ab.zip | Bin 29621 -> 0 bytes ...nsion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip | Bin 5597 -> 0 bytes ...ansion-npm-2.0.1-17aa2616f9-a61e7cd2e8.zip | Bin 0 -> 6048 bytes ...slist-npm-4.23.3-4e727c7b5b-e266d18c6c.zip | Bin 18561 -> 0 bytes ...list-npm-4.24.3-1f4e7bedfb-f5b2275730.zip} | Bin 18838 -> 18832 bytes ...e-name-npm-4.1.0-4688335533-1d966c8d2d.zip | Bin 2475 -> 0 bytes .../bytes-npm-3.0.0-19be09472d-a2b386dd81.zip | Bin 5208 -> 0 bytes .../bytes-npm-3.1.2-28b8643004-a10abf2ba7.zip | Bin 5571 -> 0 bytes ...cache-npm-15.3.0-a7e5239c6a-1432d84f3f.zip | Bin 28777 -> 0 bytes ...cache-npm-19.0.1-395cba1936-ea026b27b1.zip | Bin 0 -> 25290 bytes ...l-bind-npm-1.0.7-762763ef96-cd6fe658e0.zip | Bin 10060 -> 0 bytes ...lsites-npm-3.1.0-268f989910-072d17b6ab.zip | Bin 3763 -> 0 bytes ...se-api-npm-3.0.0-1272c2981e-db2a229383.zip | Bin 0 -> 6119 bytes ...npm-1.0.30001647-ad375193cb-fd2dacf26d.zip | Bin 864051 -> 0 bytes ...npm-1.0.30001677-11c12e06e9-e07439bdea.zip | Bin 878134 -> 0 bytes ...npm-1.0.30001690-d600e5893e-9fb4659eb0.zip | Bin 0 -> 882541 bytes .../chalk-npm-2.4.2-3ea16dd91e-3d1d103433.zip | Bin 11576 -> 0 bytes ...okidar-npm-3.6.0-3c413a828f-c327fb0770.zip | Bin 31342 -> 0 bytes ...okidar-npm-4.0.3-962354fbb4-bf2a575ea5.zip | Bin 0 -> 45885 bytes ...chownr-npm-2.0.0-638f1c9c61-c57cf9dd07.zip | Bin 2856 -> 0 bytes ...chownr-npm-3.0.0-5275e85d25-b63cb1f73d.zip | Bin 0 -> 9572 bytes ...-event-npm-1.0.3-e0ae3dcd60-b5fbdae5bf.zip | Bin 6843 -> 0 bytes ...-event-npm-1.0.4-4f22eb2c55-1762bed739.zip | Bin 0 -> 5437 bytes ...i-info-npm-3.9.0-646784ca0e-75bc67902b.zip | Bin 0 -> 9588 bytes ...an-css-npm-5.2.2-ccb3a2a994-fd018eeb81.zip | Bin 144065 -> 0 bytes ...an-css-npm-5.3.3-d2bb553a94-2db1ae37b3.zip | Bin 0 -> 146227 bytes ...-stack-npm-2.2.0-a8ce435a5c-2ac8cd2b2f.zip | Bin 3676 -> 0 bytes ...int-at-npm-1.1.0-37de5fe566-17d5666611.zip | Bin 2502 -> 0 bytes ...onvert-npm-1.9.3-1fe690075e-ffa3190250.zip | Bin 10409 -> 0 bytes ...r-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip | Bin 5071 -> 0 bytes ...colord-npm-2.9.3-5c35c27898-907a4506d7.zip | Bin 0 -> 46549 bytes ...rette-npm-2.0.16-7b996485d7-8501db5750.zip | Bin 7120 -> 0 bytes ...ette-npm-2.0.20-692d428726-0b8de48bfa.zip} | Bin 7171 -> 7176 bytes ...mander-npm-7.2.0-19178180f8-9973af1072.zip | Bin 0 -> 41315 bytes ...sible-npm-2.0.18-ee5ab04d88-58321a85b3.zip | Bin 4148 -> 0 bytes ...ession-npm-1.7.4-e0cd6afa69-469cd09790.zip | Bin 9091 -> 0 bytes ...at-map-npm-0.0.1-85a921b7ee-9680699c8e.zip | Bin 3839 -> 0 bytes ...llback-npm-2.0.0-27b00b1571-3b26bf4041.zip | Bin 5424 -> 0 bytes ...trings-npm-1.1.0-e3160e5275-27b5fa302b.zip | Bin 5891 -> 0 bytes ...sition-npm-0.5.4-2d93678616-b7f4ce176e.zip | Bin 7992 -> 0 bytes ...t-type-npm-1.0.4-3b1a5ca16b-5ea85c5293.zip | Bin 4837 -> 0 bytes ...t-type-npm-1.0.5-3e037bf9ab-585847d98d.zip | Bin 4971 -> 0 bytes ...cookie-npm-0.7.1-f01524ff99-aec6a6aa07.zip | Bin 9288 -> 0 bytes ...cookie-npm-1.0.2-7a4273d897-f5817cdc84.zip | Bin 15607 -> 0 bytes ...nature-npm-1.0.6-93f325f7f0-f4e1b0a98a.zip | Bin 3027 -> 0 bytes ...ything-npm-2.0.3-fb13168fff-ae3da717e7.zip | Bin 12592 -> 0 bytes ...re-js-npm-3.39.0-4c420e59a7-a3d34e6697.zip | Bin 1244348 -> 0 bytes ...til-is-npm-1.0.3-ca74b76c90-9de8597363.zip | Bin 3266 -> 0 bytes ...config-npm-9.0.0-47d78cf275-8bdf1dfbb6.zip | Bin 49087 -> 0 bytes ...spawn-npm-7.0.6-264bddf921-0d52657d7a.zip} | Bin 8758 -> 8759 bytes ...sorter-npm-7.2.0-b5087e1063-2acb9c13f5.zip | Bin 0 -> 23692 bytes ...plugin-npm-7.0.0-f09f3109c8-47d8f8a38c.zip | Bin 0 -> 20085 bytes ...select-npm-4.1.3-97d7b817c1-53743b2d08.zip | Bin 31627 -> 0 bytes ...select-npm-4.3.0-72f53028ec-8f7310c9af.zip | Bin 0 -> 32904 bytes ...select-npm-5.1.0-9365a79de5-d486b1e7eb.zip | Bin 0 -> 83423 bytes ...s-tree-npm-2.2.1-ee98ac48a8-1959c4b0e2.zip | Bin 0 -> 358846 bytes ...s-tree-npm-2.3.1-6540d78e26-e5e39b82eb.zip | Bin 0 -> 370966 bytes ...s-what-npm-5.1.0-9991ae71a8-3b1f0abdf1.zip | Bin 11990 -> 0 bytes ...s-what-npm-6.1.0-57f751efbb-c67a3a2d0d.zip | Bin 0 -> 23499 bytes ...ssnano-npm-7.0.6-b3934f23a5-12b1e1f2b5.zip | Bin 0 -> 4465 bytes ...efault-npm-7.0.6-2c1cf6f352-686e7652d0.zip | Bin 0 -> 8558 bytes ...-utils-npm-5.0.0-99da5e5744-89ed5b8ca5.zip | Bin 0 -> 6552 bytes .../csso-npm-5.0.5-b21e2a8b65-4036fb2b9f.zip | Bin 0 -> 199563 bytes ...sstype-npm-3.0.9-0801c4a6d7-ffa22664f3.zip | Bin 175521 -> 0 bytes ...sstype-npm-3.1.3-e9a1c85013-f593cce41f.zip | Bin 0 -> 185965 bytes .../debug-npm-2.6.9-7d4cb597dc-e07005f2b4.zip | Bin 21213 -> 0 bytes .../debug-npm-3.2.7-754e818c7a-d86fd7be2b.zip | Bin 19899 -> 0 bytes .../debug-npm-4.3.2-f0148b6afe-6a2980374e.zip | Bin 15343 -> 0 bytes .../debug-npm-4.4.0-f6efe76023-1847944c2e.zip | Bin 0 -> 15951 bytes ...ser-id-npm-5.0.0-41fa64d5bb-185bfaecec.zip | Bin 2606 -> 0 bytes ...rowser-npm-5.2.1-e2f8bca718-afab7eff7b.zip | Bin 4132 -> 0 bytes ...operty-npm-1.1.4-4cbd8efc51-abdcb2505d.zip | Bin 11658 -> 0 bytes ...y-prop-npm-3.0.0-6bb0fc1510-f28421cf9e.zip | Bin 3284 -> 0 bytes ...egates-npm-1.0.0-9b1942d75f-a51744d9b5.zip | Bin 4237 -> 0 bytes .../depd-npm-1.1.2-b0c8414da7-2ed6966fc1.zip | Bin 12198 -> 0 bytes .../depd-npm-2.0.0-b6c51a4b43-c0c8ff3607.zip | Bin 10348 -> 0 bytes ...estroy-npm-1.2.0-6a511802e2-0acb300b74.zip | Bin 4258 -> 0 bytes ...t-libc-npm-1.0.3-c30ac344d4-3849fe7720.zip | Bin 0 -> 7954 bytes ...t-node-npm-2.1.0-e8de0e94f7-832184ec45.zip | Bin 2783 -> 0 bytes ...packet-npm-5.4.0-4d0332a163-6a3827d59a.zip | Bin 14966 -> 0 bytes ...alizer-npm-1.3.2-133de2b9ce-102ea83664.zip | Bin 8599 -> 0 bytes ...alizer-npm-1.4.1-ebb24349c1-53b217bcfe.zip | Bin 0 -> 13771 bytes ...alizer-npm-2.0.0-378ebc7200-e3bf9027a6.zip | Bin 0 -> 14008 bytes ...nttype-npm-2.2.0-c37b3b15bf-24cb386198.zip | Bin 3999 -> 0 bytes ...nttype-npm-2.3.0-02de7cbfba-ee837a318f.zip | Bin 0 -> 6357 bytes ...andler-npm-4.2.2-9a6cc9317e-502cb297ba.zip | Bin 12609 -> 0 bytes ...andler-npm-4.3.1-493539c1ca-e0d2af7403.zip | Bin 0 -> 13523 bytes ...andler-npm-5.0.3-3ede73dc10-809b805a50.zip | Bin 0 -> 22513 bytes ...mutils-npm-3.2.2-290180a284-2e08842151.zip | Bin 0 -> 59073 bytes ...nwidth-npm-0.2.0-c37eb16bd1-9b1d3e1bae.zip | Bin 0 -> 3401 bytes ...-first-npm-1.1.1-33f8535b39-1b4cac778d.zip | Bin 3501 -> 0 bytes ...romium-npm-1.5.4-58d50ae1f7-ce64db25c3.zip | Bin 26152 -> 0 bytes ...omium-npm-1.5.50-c2eeb3c362-635ca4b593.zip | Bin 27032 -> 0 bytes ...omium-npm-1.5.79-447ec14608-c5b25ba04b.zip | Bin 0 -> 27530 bytes ...-regex-npm-9.2.2-e6fac8d058-915acf859c.zip | Bin 0 -> 20945 bytes ...odeurl-npm-1.0.2-f8c8454c41-e50e3d508c.zip | Bin 4440 -> 0 bytes ...odeurl-npm-2.0.0-3660bcc92a-abf5cd51b7.zip | Bin 4028 -> 0 bytes ...olve-npm-5.18.0-afcf74b9eb-e88463ef97.zip} | Bin 66445 -> 66629 bytes ...esolve-npm-5.8.3-24a728966e-46e4c12380.zip | Bin 55579 -> 0 bytes ...tities-npm-4.5.0-7cdb83b832-ede2a35c9b.zip | Bin 0 -> 118405 bytes .../errno-npm-0.1.8-10ebc185bf-93076ed11b.zip | Bin 7884 -> 0 bytes ...ror-ex-npm-1.3.2-5654f80c0f-d547740aa2.zip | Bin 4271 -> 0 bytes ...operty-npm-1.0.0-e23aa9b242-f66ece0a88.zip | Bin 7525 -> 0 bytes ...errors-npm-1.3.0-fda0c9b8a8-96e65d6401.zip | Bin 9301 -> 0 bytes ...-lexer-npm-1.3.0-9be5e8b1c4-dee2af0966.zip | Bin 30886 -> 0 bytes ...-lexer-npm-1.6.0-20500c26f6-807ee7020c.zip | Bin 0 -> 32610 bytes ...calade-npm-3.1.2-5826d31cf8-a1e07fea2f.zip | Bin 6765 -> 0 bytes ...e-html-npm-1.0.3-376c22ee74-6213ca9ae0.zip | Bin 2709 -> 0 bytes ...regexp-npm-1.0.5-3284de402f-6092fda75c.zip | Bin 2385 -> 0 bytes ...averse-npm-5.2.0-b2e8e36350-9740a8fa42.zip | Bin 10958 -> 0 bytes ...averse-npm-5.3.0-03284f8f63-37cbe6e9a6.zip | Bin 0 -> 10984 bytes .../etag-npm-1.8.1-54a3b989d9-571aeb3dbe.zip | Bin 5286 -> 0 bytes ...itter3-npm-4.0.7-7afcdd74ae-8030029382.zip | Bin 13807 -> 0 bytes ...ackoff-npm-3.1.1-04df458b30-2d9bbb6473.zip | Bin 0 -> 22892 bytes ...press-npm-4.21.2-9b3bd32250-34571c442f.zip | Bin 66251 -> 0 bytes ...-glob-npm-3.3.3-2a653be532-dcc6432b26.zip} | Bin 43215 -> 43497 bytes ...st-uri-npm-3.0.5-88ac8c7ad4-21bd8d523c.zip | Bin 0 -> 28909 bytes ...htein-npm-1.0.12-a32b4ef51e-e1a013698d.zip | Bin 6016 -> 0 bytes ...htein-npm-1.0.16-192d328856-ee85d33b5c.zip | Bin 0 -> 10052 bytes ...fastq-npm-1.13.0-a45963881c-0902cb9b81.zip | Bin 12292 -> 0 bytes ...fastq-npm-1.18.0-25fe4d7171-c5b501333d.zip | Bin 0 -> 13311 bytes ...ocket-npm-0.11.4-1f0de76de9-22433c14c6.zip | Bin 13876 -> 0 bytes ...andler-npm-1.3.1-690d7d7e6d-4babe72969.zip | Bin 8265 -> 0 bytes ...rects-npm-1.15.6-50635fe51d-70c7612c4c.zip | Bin 11162 -> 0 bytes ...-child-npm-3.3.0-b8be745271-e3a60480f3.zip | Bin 0 -> 33003 bytes ...warded-npm-0.2.0-6473dabe35-29ba9fd347.zip | Bin 3668 -> 0 bytes ...ion.js-npm-4.3.7-c2c7e95a8e-bb5ebcdeef.zip | Bin 27990 -> 0 bytes .../fresh-npm-0.5.2-ad2bb4c0a2-64c88e489b.zip | Bin 5281 -> 0 bytes ...nipass-npm-2.1.0-501ef87306-03191781e9.zip | Bin 5210 -> 0 bytes ...nipass-npm-3.0.3-d148d6ac19-af143246cf.zip | Bin 0 -> 5333 bytes ...alpath-npm-1.0.0-c8f05d8126-e703107c28.zip | Bin 5921 -> 0 bytes ...events-npm-2.3.2-a881d6ac9f-6b5b6f5692.zip | Bin 22921 -> 0 bytes .../cache/fsevents-patch-19706e7e35-10.zip | Bin 23750 -> 0 bytes ...n-bind-npm-1.1.1-b56b322ae9-d83f296803.zip | Bin 8530 -> 0 bytes .../gauge-npm-2.7.4-2189a73529-0db20a7def.zip | Bin 20131 -> 0 bytes ...rinsic-npm-1.2.4-1dad3427b2-85bbf4b234.zip | Bin 14541 -> 0 bytes .../glob-npm-10.4.5-8c63175f05-698dfe1182.zip | Bin 0 -> 138076 bytes .../glob-npm-7.2.0-bb4644d239-bc78b6ea07.zip | Bin 19539 -> 0 bytes ...lobby-npm-14.0.0-3bccdd5188-6e7d84bbc6.zip | Bin 9437 -> 0 bytes ...lobby-npm-14.0.2-28ff4422ff-67660da70f.zip | Bin 0 -> 9471 bytes .../gopd-npm-1.0.1-10c1d0b534-5fbc7ad57b.zip | Bin 5330 -> 0 bytes ...ful-fs-npm-4.2.8-37c16fc3d3-c29f627822.zip | Bin 11449 -> 0 bytes ...-thing-npm-2.0.1-084baca59e-441ec98b07.zip | Bin 5591 -> 0 bytes ...s-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip | Bin 2434 -> 0 bytes .../has-npm-1.0.3-b7f00631c1-a449f3185b.zip | Bin 2657 -> 0 bytes ...iptors-npm-1.0.2-d7077d09f1-2d8c9ab8ce.zip | Bin 6746 -> 0 bytes ...-proto-npm-1.0.3-b598da2961-0b67c2c94e.zip | Bin 7125 -> 0 bytes ...ymbols-npm-1.0.3-1986bff2c4-464f97a820.zip | Bin 10526 -> 0 bytes ...nicode-npm-2.0.1-893adb4747-041b4293ad.zip | Bin 2731 -> 0 bytes ...ack.js-npm-2.1.6-b08cc088ad-6910e4b9d9.zip | Bin 24128 -> 0 bytes ...terser-npm-6.0.2-3a759c4206-8362cab367.zip | Bin 31385 -> 0 bytes ...terser-npm-6.1.0-49a405eebd-a244fa944e.zip | Bin 0 -> 31666 bytes ...antics-npm-4.1.0-860520a31f-c9c29508b2.zip | Bin 12064 -> 0 bytes ...antics-npm-4.1.1-1120131375-362d5ed66b.zip | Bin 0 -> 11972 bytes ...ceiver-npm-1.2.7-4f3aaa5b79-9ae293b0ac.zip | Bin 5147 -> 0 bytes ...errors-npm-1.6.3-9b5bc0b0a8-e48732657e.zip | Bin 6761 -> 0 bytes ...errors-npm-2.0.0-3f1c503428-0e7f76ee8f.zip | Bin 7585 -> 0 bytes ...ser-js-npm-0.5.3-1974f4efad-6a8a609db6.zip | Bin 7440 -> 0 bytes ...-agent-npm-4.0.1-ce9ef61788-2e17f5519f.zip | Bin 8096 -> 0 bytes ...-agent-npm-7.0.2-643ed7cc33-d062acfa0c.zip | Bin 0 -> 7913 bytes ...leware-npm-2.0.7-886a673e85-4a51bf612b.zip | Bin 28805 -> 0 bytes ...proxy-npm-1.18.1-a313c479c5-2489e98aba.zip | Bin 75408 -> 0 bytes ...-agent-npm-5.0.0-bb777903c3-517037badc.zip | Bin 12033 -> 0 bytes ...-agent-npm-7.0.6-27a95c2690-784b628cbd.zip | Bin 0 -> 12319 bytes ...ize-ms-npm-1.2.1-e942bd7329-9c7a74a282.zip | Bin 2775 -> 0 bytes ...-lite-npm-0.4.24-c5c4ac6695-6d3a2dac6e.zip | Bin 192156 -> 0 bytes ...ignore-npm-5.3.0-fb0f5fa062-51594355ce.zip | Bin 19632 -> 0 bytes ...ignore-npm-5.3.2-346d3ba017-cceb6a4570.zip | Bin 0 -> 20482 bytes ...e-size-npm-0.5.5-4dec53b956-f41ec6cfcc.zip | Bin 11652 -> 0 bytes ...immer-npm-10.1.1-973ae10d09-9dacf1e8c2.zip | Bin 0 -> 179008 bytes ...utable-npm-5.0.3-c4195fd7f3-9aca1c7839.zip | Bin 0 -> 142003 bytes ...-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip | Bin 3375 -> 0 bytes ...-local-npm-3.0.3-fd16a368c1-38ae57d35e.zip | Bin 3412 -> 0 bytes ...-local-npm-3.2.0-bf54ec7842-0b0b0b412b.zip | Bin 0 -> 3763 bytes ...string-npm-4.0.0-7b717435b2-cd3f5cbc9c.zip | Bin 3164 -> 0 bytes ...-owner-npm-1.0.4-685ac3d2af-181e732764.zip | Bin 2810 -> 0 bytes ...flight-npm-1.0.6-ccedb4b908-d2ebd65441.zip | Bin 2739 -> 0 bytes ...herits-npm-2.0.3-401e64b080-8771303d66.zip | Bin 2921 -> 0 bytes ...herits-npm-2.0.4-c66b3957a0-cd45e923be.zip | Bin 2949 -> 0 bytes ...ddress-npm-9.0.5-9fa024d42a-1ed81e0672.zip | Bin 0 -> 55735 bytes .../ip-npm-1.1.9-e72dd3cc0a-29261559b8.zip | Bin 5873 -> 0 bytes ...ddr.js-npm-1.9.1-19ae7878b4-864d0cced0.zip | Bin 13518 -> 0 bytes ...ddr.js-npm-2.1.0-7091ce1549-42c16d95cf.zip | Bin 17396 -> 0 bytes ...rayish-npm-0.2.1-23927dfb15-73ced84fa3.zip | Bin 3896 -> 0 bytes ...y-path-npm-2.1.0-e61d46f557-078e51b4f9.zip | Bin 2655 -> 0 bytes ...odule-npm-2.11.0-70061e141a-9b09ce78f1.zip | Bin 10586 -> 0 bytes ...odule-npm-2.16.1-a54837229e-452b2c2fb7.zip | Bin 0 -> 11996 bytes ...docker-npm-3.0.0-1570e32177-b698118f04.zip | Bin 2862 -> 0 bytes ...-point-npm-1.0.0-0e436ba1ef-4d46a7465a.zip | Bin 3002 -> 0 bytes ...tainer-npm-1.0.0-f2c9e9bb96-c50b75a2ab.zip | Bin 3148 -> 0 bytes ...lambda-npm-1.0.1-7ab55bc8a8-93a32f0194.zip | Bin 2925 -> 0 bytes ...-error-npm-1.0.1-e7ca0446b3-165d61500c.zip | Bin 3493 -> 0 bytes ...in-obj-npm-3.0.0-a5ae411d5a-a6ebdf8e12.zip | Bin 3018 -> 0 bytes ...-what-npm-3.14.1-7260378616-249beb4a8c.zip | Bin 18342 -> 0 bytes ...is-wsl-npm-3.1.0-311c6d2265-f9734c81f2.zip | Bin 2839 -> 0 bytes ...sarray-npm-1.0.0-db4f547720-f032df8e02.zip | Bin 3372 -> 0 bytes .../isexe-npm-3.1.1-9c0061eead-7fe1931ee4.zip | Bin 0 -> 23319 bytes ...kspeak-npm-3.4.3-546bfad080-96f8786eaa.zip | Bin 0 -> 72557 bytes ...-util-npm-29.7.0-ff1d59714b-30d58af696.zip | Bin 0 -> 22214 bytes ...orker-npm-29.7.0-4d3567fed6-364cbaef00.zip | Bin 0 -> 34534 bytes .../jiti-npm-1.21.0-baebd5985a-005a0239e5.zip | Bin 407936 -> 0 bytes ...tokens-npm-4.0.0-0ac852e9e2-af37d0d913.zip | Bin 7686 -> 0 bytes ...s-yaml-npm-4.1.0-3606f32312-c138a34a3f.zip | Bin 113890 -> 0 bytes .../jsbn-npm-1.1.0-1da0181838-bebe7ae829.zip | Bin 0 -> 15409 bytes ...editor-npm-2.6.1-0aba6b0e98-e06d193075.zip | Bin 6715 -> 0 bytes ...oader-npm-12.2.0-19b77fcf7d-b952705346.zip | Bin 11920 -> 0 bytes .../less-npm-4.2.1-300918da9f-931343f468.zip | Bin 774770 -> 0 bytes ...config-npm-3.1.3-74a77377bb-b932ce1af9.zip | Bin 0 -> 6424 bytes ...olumns-npm-1.1.6-23e74fab67-198a5436b1.zip | Bin 4075 -> 0 bytes ...runner-npm-4.2.0-427f0e7134-89a648e041.zip | Bin 6995 -> 0 bytes ...runner-npm-4.3.0-9ca67df372-555ae00286.zip | Bin 0 -> 6988 bytes ...emoize-npm-4.1.2-0e6250041f-192b2168f3.zip | Bin 0 -> 7021 bytes ...h.uniq-npm-4.5.0-7c270dca85-86246ca64a.zip | Bin 0 -> 7813 bytes ...cache-npm-10.4.3-30c10b861a-e6e9026736.zip | Bin 0 -> 194674 bytes ...-cache-npm-6.0.0-b4c8668fe1-fc1fe2ee20.zip | Bin 6593 -> 0 bytes ...ke-dir-npm-2.1.0-1ddaf205e7-043548886b.zip | Bin 4843 -> 0 bytes ...appen-npm-14.0.3-23b30e8691-fce0385840.zip | Bin 0 -> 21099 bytes ...happen-npm-9.1.0-23184ad7f6-a868e74fc2.zip | Bin 22550 -> 0 bytes ...-data-npm-2.0.28-9e644d5992-aec475e0c0.zip | Bin 0 -> 90115 bytes ...-data-npm-2.0.30-bf7b39c09a-e4944322bf.zip | Bin 0 -> 91410 bytes ...-typer-npm-0.3.0-8674f8f0f5-38e0984db3.zip | Bin 5179 -> 0 bytes .../memfs-npm-4.7.6-79bbc6057e-b2a4c95635.zip | Bin 281346 -> 0 bytes ...iptors-npm-1.0.3-10b44ad75c-52117adbe0.zip | Bin 3435 -> 0 bytes ...ethods-npm-1.1.2-92f6fdb39b-a385dd974f.zip | Bin 3440 -> 0 bytes ...me-db-npm-1.50.0-ee51ad7b30-4d553dbf8b.zip | Bin 27925 -> 0 bytes .../mime-npm-1.6.0-60ae95038a-b7d98bb1e0.zip | Bin 17233 -> 0 bytes ...types-npm-2.1.33-41bfef7da1-772635f7fe.zip | Bin 6676 -> 0 bytes ...plugin-npm-2.9.2-63828e7891-db6ddb8ba5.zip | Bin 0 -> 38967 bytes ...assert-npm-1.0.1-dc8bb23d29-cc7974a926.zip | Bin 1788 -> 0 bytes ...imatch-npm-3.1.2-9405269906-e0b25b04cd.zip | Bin 12889 -> 0 bytes ...imatch-npm-9.0.5-9aa93d97fa-dd6a8927b0.zip | Bin 0 -> 127977 bytes ...ollect-npm-1.0.2-3b4676eab5-14df761028.zip | Bin 2858 -> 0 bytes ...ollect-npm-2.0.1-73d3907e40-b251bceea6.zip | Bin 0 -> 2918 bytes ...-fetch-npm-1.4.1-2d67357feb-4c6f678d2c.zip | Bin 16437 -> 0 bytes ...-fetch-npm-4.0.0-d4e49e0194-4b0772dbee.zip | Bin 0 -> 17458 bytes ...nipass-npm-3.1.5-63d27aa1b8-e41da4d983.zip | Bin 13373 -> 0 bytes ...nipass-npm-3.3.6-b8d93a945b-a5c6ef069f.zip | Bin 0 -> 16570 bytes ...nipass-npm-5.0.0-c64fb63c92-61682162d2.zip | Bin 22402 -> 0 bytes ...nipass-npm-7.1.2-3a5327d36d-c25f0ee819.zip | Bin 0 -> 73627 bytes ...nizlib-npm-2.1.2-ea89cd0cfb-ae0f45436f.zip | Bin 7140 -> 0 bytes ...nizlib-npm-3.0.1-4bdabd978f-622cb85f51.zip | Bin 0 -> 34800 bytes ...mkdirp-npm-1.0.4-37f6ef56b9-d71b8dcd4b.zip | Bin 9796 -> 0 bytes ...mkdirp-npm-3.0.1-f94bfa769e-16fd79c286.zip | Bin 0 -> 46067 bytes .../ms-npm-2.0.0-9e1101a471-0e6a22b8b7.zip | Bin 3478 -> 0 bytes .../ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip | Bin 3647 -> 0 bytes ...st-dns-npm-7.2.5-e1c9c3ec64-e9add8035f.zip | Bin 8179 -> 0 bytes ...needle-npm-3.2.0-7773d3d8c8-65ec7c7166.zip | Bin 74327 -> 0 bytes ...tiator-npm-0.6.2-ba538e167a-eaf267fedd.zip | Bin 11064 -> 0 bytes ...tiator-npm-0.6.3-9d50e36171-2723fb822a.zip | Bin 10848 -> 0 bytes ...tiator-npm-1.0.0-47d727e27e-b5734e8729.zip | Bin 0 -> 11192 bytes ...on-api-npm-7.1.1-bfb302df19-ee1e1ed628.zip | Bin 0 -> 65714 bytes ...-forge-npm-1.3.1-f31fd566cc-05bab68686.zip | Bin 467833 -> 0 bytes ...e-gyp-npm-11.0.0-669e34db1b-5d07430e88.zip | Bin 0 -> 505732 bytes ...de-gyp-npm-8.3.0-11e93b166f-8d1c0d8f80.zip | Bin 506666 -> 0 bytes ...eases-npm-2.0.18-51abc46668-241e5fa955.zip | Bin 5981 -> 0 bytes ...eases-npm-2.0.19-b123ed6240-c2b33b4f0c.zip | Bin 0 -> 6097 bytes .../nopt-npm-5.0.0-304b40fbfe-00f9bb2d16.zip | Bin 10663 -> 0 bytes .../nopt-npm-8.0.0-98d6bf6d52-2d137f64b6.zip | Bin 0 -> 11138 bytes ...-range-npm-0.1.2-bec5e259e2-9b2f14f093.zip | Bin 4084 -> 0 bytes ...ze.css-npm-8.0.1-6124fb39b6-c3af2145c2.zip | Bin 7175 -> 0 bytes ...npmlog-npm-4.1.2-cfb32957b5-b6b85c9f33.zip | Bin 7489 -> 0 bytes ...-check-npm-2.0.1-69558042d2-5386d035c4.zip | Bin 8412 -> 0 bytes ...-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip | Bin 0 -> 21244 bytes ...is-nan-npm-1.0.1-845325a0fe-13656bc9aa.zip | Bin 2176 -> 0 bytes ...assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip | Bin 3454 -> 0 bytes ...spect-npm-1.13.2-3c6e11a536-7ef65583b6.zip | Bin 36365 -> 0 bytes .../obuf-npm-1.1.2-8db5fae8dd-53ff4ab3a1.zip | Bin 5034 -> 0 bytes ...nished-npm-2.4.1-907af70f88-8e81472c50.zip | Bin 6210 -> 0 bytes ...eaders-npm-1.0.2-e7cd3ea25e-870766c163.zip | Bin 4229 -> 0 bytes .../once-npm-1.4.0-ccf03ef07a-cd0a885013.zip | Bin 2595 -> 0 bytes .../open-npm-10.0.3-fafc8b8513-4dc757ad1d.zip | Bin 16504 -> 0 bytes .../p-map-npm-4.0.0-4677ae07c7-7ba4a2b1e2.zip | Bin 4836 -> 0 bytes .../p-map-npm-7.0.3-93bbec0d8c-2ef48ccfc6.zip | Bin 0 -> 8187 bytes ...-retry-npm-6.2.0-00c071e02c-1a5ac16828.zip | Bin 6333 -> 0 bytes ...m-dist-npm-1.0.1-4631a88465-58ee9538f2.zip | Bin 0 -> 14065 bytes ...module-npm-1.0.1-1fae11b095-6ba8b25514.zip | Bin 2797 -> 0 bytes ...e-json-npm-5.2.0-00a63b1199-62085b17d6.zip | Bin 3421 -> 0 bytes ...ersion-npm-1.0.1-7dd3b14751-ac9b40c647.zip | Bin 3072 -> 0 bytes ...rseurl-npm-1.3.3-1542397e00-407cee8e0a.zip | Bin 4978 -> 0 bytes ...solute-npm-1.0.1-31bc695ffd-060840f92c.zip | Bin 2649 -> 0 bytes ...curry-npm-1.11.1-aaf8c339af-5e8845c159.zip | Bin 0 -> 110494 bytes ...egexp-npm-0.1.12-a9bf1de212-2e30f6a014.zip | Bin 3823 -> 0 bytes ...colors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip | Bin 3741 -> 0 bytes ...colors-npm-1.0.1-39442f3da8-fa68166d1f.zip | Bin 3757 -> 0 bytes ...colors-npm-1.1.0-ea12a640bd-a2ad60d94d.zip | Bin 5774 -> 0 bytes .../pify-npm-4.0.1-062756097b-8b97cbf9dc.zip | Bin 4041 -> 0 bytes ...-calc-npm-10.1.0-3964347659-e1e61c618f.zip | Bin 0 -> 44249 bytes ...lormin-npm-7.0.2-08a84f84c2-cb83d95d21.zip | Bin 0 -> 6691 bytes ...values-npm-7.0.4-709e2a2326-077481cc98.zip | Bin 0 -> 8113 bytes ...mments-npm-7.0.3-7bca5e8784-f7c994df0d.zip | Bin 0 -> 8353 bytes ...icates-npm-7.0.1-96084cdabe-0c757bb542.zip | Bin 0 -> 4628 bytes ...-empty-npm-7.0.0-01e04915c0-0c5cea1980.zip | Bin 0 -> 3892 bytes ...ridden-npm-7.0.0-dc7733ab45-e41c448305.zip | Bin 0 -> 3568 bytes ...loader-npm-8.1.1-20cf547c92-7ae38e6351.zip | Bin 15066 -> 0 bytes ...nghand-npm-7.0.4-4ca1c9a93a-b94b98a9b2.zip | Bin 0 -> 37552 bytes ...-rules-npm-7.0.4-c94fbbce93-f67a4f6e81.zip | Bin 0 -> 10663 bytes ...values-npm-7.0.0-f4e2caa8b1-8578c1d1d4.zip | Bin 0 -> 12230 bytes ...dients-npm-7.0.0-f7b51ae77b-9649e255ad.zip | Bin 0 -> 6172 bytes ...params-npm-7.0.2-1cbb800885-26b6ce4db3.zip | Bin 0 -> 5058 bytes ...ectors-npm-7.0.4-bbc44478a3-54c74dcb09.zip | Bin 0 -> 6770 bytes ...efault-npm-4.0.5-1a623b43f9-b08b01aa7f.zip | Bin 7524 -> 0 bytes ...efault-npm-4.2.0-3f37e3939f-552329aa39.zip | Bin 0 -> 8535 bytes ...scope-npm-3.2.1-eb0a0538a7-51c747fa15.zip} | Bin 5844 -> 6939 bytes ...harset-npm-7.0.0-bdacb840f9-a41043fb81.zip | Bin 0 -> 4064 bytes ...values-npm-7.0.0-6a9992d76e-55bbfb4dac.zip | Bin 0 -> 5625 bytes ...itions-npm-7.0.0-75155a14d6-a6b982e567.zip | Bin 0 -> 4839 bytes ...-style-npm-7.0.0-2af427828c-f8ef8cf5ac.zip | Bin 0 -> 5900 bytes ...string-npm-7.0.0-0e5f6f1917-23ea7dd7b2.zip | Bin 0 -> 5824 bytes ...ctions-npm-7.0.0-7f393fd35d-f85870b3c8.zip | Bin 0 -> 4579 bytes ...nicode-npm-7.0.2-3d756de91e-cb342f7507.zip | Bin 0 -> 4934 bytes ...ze-url-npm-7.0.0-055009149a-c5edca0646.zip | Bin 0 -> 6937 bytes ...espace-npm-7.0.0-8bed345e63-c409362e32.zip | Bin 0 -> 4384 bytes ...stcss-npm-8.4.33-6ba8157009-e22a4594c2.zip | Bin 66301 -> 0 bytes ...values-npm-7.0.1-f37f91ed1f-048082c09e.zip | Bin 0 -> 23589 bytes ...nitial-npm-7.0.2-e37256f84c-5a8260cbf7.zip | Bin 0 -> 9256 bytes ...sforms-npm-7.0.0-653cd9844a-1c369a1be8.zip | Bin 0 -> 4841 bytes ...parser-npm-6.0.6-4df491c1e3-1afbfdf60b.zip | Bin 85235 -> 0 bytes ...parser-npm-6.1.2-46a8e03b00-190034c94d.zip | Bin 0 -> 60528 bytes ...parser-npm-7.0.0-7bb98f14d5-0e92be7281.zip | Bin 0 -> 60556 bytes ...s-svgo-npm-7.0.1-22674c6627-4196d9b7ec.zip | Bin 0 -> 7590 bytes ...ectors-npm-7.0.3-bbadc7397e-c38ca6b5f5.zip | Bin 0 -> 4116 bytes ...parser-npm-4.1.0-4620e3e849-dac294ad5f.zip | Bin 10210 -> 0 bytes ...oc-log-npm-5.0.0-405173f9b4-35610bdb01.zip | Bin 0 -> 4798 bytes ...k-args-npm-2.0.1-b8d7971609-1d38588e52.zip | Bin 2477 -> 0 bytes ...flight-npm-1.0.1-5bb925afac-1560d413ea.zip | Bin 2469 -> 0 bytes ...y-addr-npm-2.0.7-dae6552872-f24a0c80af.zip | Bin 6600 -> 0 bytes .../prr-npm-1.0.1-608d442761-3bca2db047.zip | Bin 4631 -> 0 bytes ...nycode-npm-2.1.1-26eb3e15cf-939daa010c.zip | Bin 12529 -> 0 bytes ...nycode-npm-2.3.1-97543c420d-febdc4362b.zip | Bin 0 -> 12956 bytes .../qs-npm-6.13.0-53676ddc84-f548b376e6.zip | Bin 59850 -> 0 bytes ...parser-npm-1.2.1-1a470fa390-ce21ef2a2d.zip | Bin 4716 -> 0 bytes ...w-body-npm-2.5.2-5cb9dfebc1-863b5171e1.zip | Bin 10604 -> 0 bytes ...er-dom-npm-7.1.1-e7e2c37675-d7b978959f.zip | Bin 4072 -> 0 bytes ...router-npm-7.1.1-b009809927-f12e229d79.zip | Bin 542252 -> 0 bytes ...stream-npm-2.3.7-77b22a9818-d04c677c17.zip | Bin 36282 -> 0 bytes ...stream-npm-3.6.0-23a4a5eb56-b80b3e6a7f.zip | Bin 45941 -> 0 bytes ...addirp-npm-3.6.0-f950cc74ab-196b30ef6c.zip | Bin 8740 -> 0 bytes ...addirp-npm-4.0.2-8001f0febc-4ef9310330.zip | Bin 0 -> 12449 bytes ...s-port-npm-1.0.0-fd036b488a-878880ee78.zip | Bin 4276 -> 0 bytes ...e-from-npm-4.0.0-f758ec21bf-91eb76ce83.zip | Bin 2902 -> 0 bytes ...lve-npm-1.22.10-d6fd9cdec7-0a398b44da.zip} | Bin 60526 -> 59881 bytes ...> resolve-patch-b5982cfa8c-d4d878bfe3.zip} | Bin 61777 -> 61132 bytes ...retry-npm-0.13.1-89eb100ab6-6125ec2e06.zip | Bin 8667 -> 0 bytes ...rimraf-npm-3.0.2-2cb7dac69a-063ffaccaa.zip | Bin 7742 -> 0 bytes ...imraf-npm-5.0.10-d0c6647697-f3b8ce81ee.zip | Bin 0 -> 107452 bytes ...script-npm-7.0.0-b061c2c4fa-b02462454d.zip | Bin 3263 -> 0 bytes ...buffer-npm-5.1.2-c27fedf6c4-7eb5b48f2e.zip | Bin 11094 -> 0 bytes ...oader-npm-16.0.4-58fd3a0682-16e3552e04.zip | Bin 0 -> 18899 bytes .../sass-npm-1.83.1-543e7bb3e0-ee4ea5573f.zip | Bin 0 -> 910733 bytes .../sax-npm-1.2.4-178f05f12f-09b79ff6dc.zip | Bin 16133 -> 0 bytes ...-utils-npm-3.1.1-8704647575-cfcf991f10.zip | Bin 19395 -> 0 bytes ...-utils-npm-4.0.0-4b7d8bb168-b1bbf840a6.zip | Bin 19545 -> 0 bytes ...-utils-npm-4.2.0-e822c5b02e-808784735e.zip | Bin 22405 -> 0 bytes ...-utils-npm-4.3.0-6f0a75e2e2-86c5a7c72a.zip | Bin 0 -> 24419 bytes ...t-hose-npm-2.0.0-8ce63adb52-08cdd629a3.zip | Bin 7191 -> 0 bytes ...signed-npm-2.4.1-1ca1b883c5-52536623f1.zip | Bin 10968 -> 0 bytes ...semver-npm-5.7.2-938ee91eaa-fca14418a1.zip | Bin 19314 -> 0 bytes ...semver-npm-7.3.8-25a996cb4f-c8c04a4d41.zip | Bin 38248 -> 0 bytes ...semver-npm-7.5.4-c4ad957fcd-985dec0d37.zip | Bin 39956 -> 0 bytes ...semver-npm-7.6.3-57e82c14d5-36b1fbe1a2.zip | Bin 0 -> 40864 bytes .../send-npm-0.19.0-4297594770-1f6064dea0.zip | Bin 17374 -> 0 bytes ...script-npm-6.0.1-fac87289ed-f756b1ff34.zip | Bin 7327 -> 0 bytes ...-index-npm-1.9.1-4927052df8-2adce2878d.zip | Bin 87019 -> 0 bytes ...tatic-npm-1.16.2-5d8e560aec-7fa9d9c680.zip | Bin 9798 -> 0 bytes ...ocking-npm-2.0.0-49e2cffa24-8980ebf7ae.zip | Bin 3206 -> 0 bytes ...parser-npm-2.7.1-0e92d9e679-c92b113003.zip | Bin 7285 -> 0 bytes ...length-npm-1.2.2-243073748b-505d62b8e0.zip | Bin 8356 -> 0 bytes ...typeof-npm-1.1.0-7d8becb375-02d2564e02.zip | Bin 2308 -> 0 bytes ...typeof-npm-1.2.0-0fedbdcd3a-fde1630422.zip | Bin 3292 -> 0 bytes ...-quote-npm-1.8.1-fcccf06093-af19ab5a1e.zip | Bin 20518 -> 0 bytes ...hannel-npm-1.0.6-511657386f-eb10944f38.zip | Bin 10878 -> 0 bytes ...l-exit-npm-3.0.5-dd7570d7b8-a1d3d0d63f.zip | Bin 4819 -> 0 bytes ...l-exit-npm-4.1.0-61fb957687-c9fa63bbbd.zip | Bin 0 -> 32171 bytes ...ockjs-npm-0.3.24-ecb3909016-36312ec977.zip | Bin 29465 -> 0 bytes .../socks-npm-2.6.1-09133d0d22-6ae166bd1a.zip | Bin 43975 -> 0 bytes .../socks-npm-2.8.3-3532b59899-ffcb622c22.zip | Bin 0 -> 44723 bytes ...-agent-npm-6.1.0-b9990e465a-7e7116590c.zip | Bin 8414 -> 0 bytes ...-agent-npm-8.0.5-24d77a90dc-ee99e1daca.zip | Bin 0 -> 8369 bytes ...map-js-npm-1.0.2-ee4f9f9b30-38e2d2dd18.zip | Bin 45723 -> 0 bytes ...port-npm-0.5.21-09ca99e250-8317e12d84.zip} | Bin 28813 -> 29043 bytes .../spdy-npm-4.0.2-7e5782a993-d29b89e48e.zip | Bin 20983 -> 0 bytes ...nsport-npm-3.0.0-9f4f73f332-b93b606b20.zip | Bin 44841 -> 0 bytes ...ntf-js-npm-1.1.3-b99efd75b2-e7587128c4.zip | Bin 0 -> 15275 bytes .../ssri-npm-12.0.0-97c0e53d2e-7024c1a6e3.zip | Bin 0 -> 12635 bytes .../ssri-npm-8.0.1-a369e72ce2-fde247b710.zip | Bin 15385 -> 0 bytes ...atuses-npm-1.5.0-f88f91b2e9-c469b9519d.zip | Bin 5636 -> 0 bytes ...atuses-npm-2.0.1-81d2b97fee-18c7623fdb.zip | Bin 5925 -> 0 bytes ...-width-npm-1.0.2-01031f9add-5c79439e95.zip | Bin 2857 -> 0 bytes ...-width-npm-5.1.2-bf60531341-7369deaa29.zip | Bin 0 -> 3889 bytes ...ecoder-npm-1.1.1-e46a6c1353-7c41c17ed4.zip | Bin 6466 -> 0 bytes ...p-ansi-npm-3.0.1-6aec1365b9-9b974de611.zip | Bin 2447 -> 0 bytes ...p-ansi-npm-7.1.0-7453b80b79-475f53e9c4.zip | Bin 0 -> 3247 bytes ...ehacks-npm-7.0.4-167ad0c843-fc9d6b1e0b.zip | Bin 0 -> 31311 bytes ...-color-npm-5.5.0-183ac537bc-5f505c6fa3.zip | Bin 4019 -> 0 bytes .../svgo-npm-3.3.2-69e1d32944-82fdea9b93.zip | Bin 0 -> 398049 bytes .../tar-npm-6.2.1-237800bb20-bfbfbb2861.zip | Bin 52576 -> 0 bytes .../tar-npm-7.4.3-1dbbd1ffc3-12a2a4fc6d.zip | Bin 0 -> 354195 bytes ...erser-npm-5.15.1-63dec1247d-9b7cf2b40b.zip | Bin 430097 -> 0 bytes ...erser-npm-5.27.0-c18b449e2e-9b2c5cb007.zip | Bin 449297 -> 0 bytes ...erser-npm-5.37.0-7dbdc43c6e-3afacf7c38.zip | Bin 0 -> 469374 bytes ...ugin-npm-5.3.11-1a5bba0883-a8f7c92c75.zip} | Bin 22976 -> 22979 bytes ...thunky-npm-1.1.0-2d25531f44-825e3bd07a.zip | Bin 4274 -> 0 bytes ...tifier-npm-1.0.1-f759712599-952c29e2a8.zip | Bin 3357 -> 0 bytes .../tslib-npm-2.3.1-0e21e18015-5e7de59ed9.zip | Bin 14043 -> 0 bytes .../tslib-npm-2.6.2-4fc8c068d9-bd26c22d36.zip | Bin 26575 -> 0 bytes .../tslib-npm-2.8.1-66590b21b8-3e2e043d5c.zip | Bin 0 -> 28416 bytes ...stream-npm-2.4.0-e0cec53097-7079bbc82b.zip | Bin 15318 -> 0 bytes ...pe-is-npm-1.6.18-6dee4d4961-0bd9eeae5e.zip | Bin 7029 -> 0 bytes ...lename-npm-1.1.1-c885c5095b-9b6969d649.zip | Bin 18331 -> 0 bytes ...lename-npm-4.0.0-bfc100c4e3-6a62094fca.zip | Bin 0 -> 2747 bytes ...e-slug-npm-2.0.2-f6ba1ddeb7-6cfaf91976.zip | Bin 2797 -> 0 bytes ...e-slug-npm-5.0.0-11508c0469-beafdf3d6f.zip | Bin 0 -> 2424 bytes ...unpipe-npm-1.0.0-2ed2a3c2bf-4fa18d8d8d.zip | Bin 3010 -> 0 bytes ...ist-db-npm-1.1.0-3d2cb7d955-d70b9efeaf.zip | Bin 7036 -> 0 bytes ...-store-npm-1.4.0-176448bea1-08bf581a8a.zip | Bin 0 -> 14784 bytes ...-merge-npm-1.0.1-363bbdfbca-5d6949693d.zip | Bin 2853 -> 0 bytes .../uuid-npm-8.3.2-eca0baba53-9a5f7aa1d6.zip | Bin 57078 -> 0 bytes .../vary-npm-1.1.2-b49f70ae63-31389debef.zip | Bin 4660 -> 0 bytes ...hpack-npm-2.4.2-3e587d5d5b-6bd4c051d9.zip} | Bin 17472 -> 17513 bytes .../wbuf-npm-1.7.3-cc9e10a084-c18b51c4e1.zip | Bin 5539 -> 0 bytes ...leware-npm-7.4.2-4c13142935-608d101b82.zip | Bin 42078 -> 0 bytes ...server-npm-5.2.0-baf75bbb61-f93ca46b03.zip | Bin 119415 -> 0 bytes ...driver-npm-0.7.4-a72739da70-17197d265d.zip | Bin 27498 -> 0 bytes ...nsions-npm-0.1.4-be839a9e56-b5399b487d.zip | Bin 19781 -> 0 bytes .../which-npm-5.0.0-15aa39eb60-6ec99e89ba.zip | Bin 0 -> 4504 bytes ...-align-npm-1.1.5-889d77e592-d5f8027b9a.zip | Bin 2750 -> 0 bytes ...p-ansi-npm-7.0.0-ad6e1a0554-cebdaeca3a.zip | Bin 0 -> 5104 bytes ...p-ansi-npm-8.1.0-26a4e6ae28-7b1e4b35e9.zip | Bin 0 -> 5882 bytes ...wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip | Bin 2344 -> 0 bytes .../ws-npm-8.18.0-56f68bc4d6-70dfe53f23.zip | Bin 41783 -> 0 bytes ...allist-npm-5.0.0-8732dd9f1c-1884d272d4.zip | Bin 0 -> 18535 bytes ...ustand-npm-4.5.6-b96df5a380-9efd6faca8.zip | Bin 0 -> 127994 bytes app-frontend/app/index.html | 9 +- app-frontend/app/src/app.tsx | 37 + app-frontend/app/src/components/NavLink.tsx | 46 + .../src/components/NavigationComponent.tsx | 19 + .../app/src/components/ThemeSwitch.tsx | 29 + .../src/components/bar/{bar.less => bar.scss} | 0 app-frontend/app/src/components/bar/bar.tsx | 19 +- .../src/components/bar/useVersionsStore.ts | 15 + .../category/{category.less => category.scss} | 18 +- .../app/src/components/category/category.tsx | 11 +- .../app/src/components/footer/Footer.tsx | 18 + .../components/head/{head.less => head.scss} | 0 app-frontend/app/src/components/head/head.tsx | 8 +- .../src/components/head/kotlin-14-event.png | Bin 52055 -> 0 bytes app-frontend/app/src/components/head/logos.ts | 46 +- .../components/list/{list.less => list.scss} | 19 +- app-frontend/app/src/components/list/list.tsx | 11 +- .../listitem/{listitem.less => listitem.scss} | 22 +- .../app/src/components/listitem/listitem.tsx | 7 +- .../components/login_button/github-logo.svg | 13 + .../components/login_button/loginButton.tsx | 17 + .../app/src/components/navigation/navbar.tsx | 67 + .../components/navigation/navbar_default.tsx | 29 + .../{Navigation.less => navigation.scss} | 8 +- .../navigation/{Navigation.tsx => nv.tsx} | 9 +- .../components/page_wrapper/page_wrapper.less | 1 - .../components/page_wrapper/page_wrapper.scss | 77 + .../components/page_wrapper/page_wrapper.tsx | 180 +- .../search/{search.less => search.scss} | 15 +- .../app/src/components/search/search.tsx | 67 +- ...KotlinVersion.less => kotlin_version.scss} | 0 .../{KotlinVersion.tsx => kotlin_version.tsx} | 15 +- .../src/components/war/SupportUkraine.scss | 25 + .../app/src/components/war/SupportUkraine.tsx | 15 + app-frontend/app/src/hooks/useFocus.ts | 15 + .../src/hooks/useForceUpdateEverySecond.ts | 15 + app-frontend/app/src/index.tsx | 50 + app-frontend/app/src/links.ts | 31 - app-frontend/app/src/locations.tsx | 11 - app-frontend/app/src/main.tsx | 14 - app-frontend/app/src/pages/404/404.scss | 6 + app-frontend/app/src/pages/404/404.tsx | 38 + app-frontend/app/src/pages/home/home.tsx | 10 +- app-frontend/app/src/pages/kugs/kugs.tsx | 10 +- app-frontend/app/src/pages/login/login.tsx | 34 + .../app/src/pages/resources/resources.tsx | 10 +- app-frontend/app/src/root.tsx | 23 - app-frontend/app/src/store/themeStore.ts | 24 + app-frontend/app/src/store/useLinksStore.ts | 33 + .../app/src/store/useNavigationStore.ts | 74 + app-frontend/app/src/style.less | 10 - app-frontend/app/src/style.scss | 80 + app-frontend/app/src/useFetch.ts | 126 + app-frontend/app/src/utils/queryParams.ts | 7 + app-frontend/app/src/vars.less | 11 - app-frontend/app/src/vars.scss | 11 + app-frontend/default.conf | 24 - app-frontend/package.json | 26 +- app-frontend/root/robots.txt | 2 - app-frontend/webpack.config.js | 102 +- app-frontend/yarn.lock | 4459 ++++------ .../2016-03912acb0d3a7411a52197d3.awesome.kts | 24 - .../2016-1efc8ffce3cc834925aa4c38.awesome.kts | 24 - .../2016-2ffeed9d6973c35ce9706715.awesome.kts | 24 - .../2016-49c21892145da64d0da7dd46.awesome.kts | 23 - .../2016-649e83c4a07f241634f53c7e.awesome.kts | 24 - .../2016-6ac57131c47ae1976f77dd2f.awesome.kts | 24 - .../2016-8cb358f24247fb7b3dde2c1c.awesome.kts | 24 - .../2016-8ede24c8c6a721e457b5d938.awesome.kts | 24 - .../2016-aa65c0e237d34255db9ebbf7.awesome.kts | 24 - .../2016-ba90e857935f39092d04eca4.awesome.kts | 24 - .../2016-bb8a72dbab79838a6d8d73b3.awesome.kts | 24 - .../2016-c4e9708d1c40343edae010d8.awesome.kts | 24 - .../2016-cca2521e1d43b3500fdcedca.awesome.kts | 24 - .../2013-310339fbf044daa921b21330.awesome.kts | 197 - .../2013-3553198685da07c3d7471120.awesome.kts | 158 - .../2013-606d6240cb4d33d6e450f3ed.awesome.kts | 267 - .../2013-6df01930de5b789cd543654f.awesome.kts | 165 - .../2013-9c60e81b64022807e89e7959.awesome.kts | 162 - .../2014-21b41e58c62d3041fe869125.awesome.kts | 24 - .../2014-25db6ff51cff9ccd18039078.awesome.kts | 25 - .../2014-2d0c6e46aab919046ef7eded.awesome.kts | 25 - .../2014-f6830c7ecbc9f2a1f5f5f26b.awesome.kts | 73 - .../2015-0deb11e93b9810ab1e0b2d88.awesome.kts | 403 - .../2015-15e1560ec7019761a6e8a840.awesome.kts | 390 - .../2015-1dcdb00cb7aeabd57155a7e1.awesome.kts | 50 - .../2015-278ad978c3f24481040018c2.awesome.kts | 108 - .../2015-375012f9875f861a8b437791.awesome.kts | 394 - .../2015-4376c2267cd589d6f0ad3865.awesome.kts | 222 - .../2015-580c3801999022ec81486732.awesome.kts | 26 - .../2015-63d0ff8dec6f4b6024e40a03.awesome.kts | 68 - .../2015-6a426a1822c1adf0e115b223.awesome.kts | 25 - .../2015-79b0262f809a3a842cc1fc3a.awesome.kts | 411 - .../2015-7c5d147026965c6474e4953c.awesome.kts | 114 - .../2015-7f4116d2a6ad6ffb8bbd2d4e.awesome.kts | 69 - .../2015-98e68615d111e1b1e739e31a.awesome.kts | 455 - .../2015-a9ae3757b968a8e9a176e802.awesome.kts | 26 - .../2015-aefed04e1f5bf7b44595ae36.awesome.kts | 187 - .../2015-cb227cfc53c63a8a9b95fffa.awesome.kts | 313 - .../2015-e2381c8c7280e63c473af5fe.awesome.kts | 56 - .../2015-f6140fef22f02a7af341088a.awesome.kts | 171 - .../2016-0255f596f7c3d38317b38136.awesome.kts | 32 - .../2016-027aae71a81a93d02678e90f.awesome.kts | 140 - .../2016-02ba3f66f0b171f296f83fbe.awesome.kts | 184 - .../2016-02e8a7d319a3f808ba2fdf55.awesome.kts | 118 - .../2016-034667ecfbc594d76a3d1c6e.awesome.kts | 148 - .../2016-069a24229854109b1de94ada.awesome.kts | 141 - .../2016-06e38c50d6f21f2e6f9fa26f.awesome.kts | 225 - .../2016-07fad586977736c6dd7ee1e6.awesome.kts | 129 - .../2016-08597c8863d0a4eca032abd3.awesome.kts | 86 - .../2016-08965fd81d86020ef1515f43.awesome.kts | 232 - .../2016-08db274630a60c20d57e7f5a.awesome.kts | 81 - .../2016-094b5bd4ba588cdf7e82fabb.awesome.kts | 242 - .../2016-0a9ea2fe281aaf2111e1b7d1.awesome.kts | 164 - .../2016-0c7e82fb01baa5f523161cb1.awesome.kts | 157 - .../2016-0d0928e9334d0f7a8b412ae3.awesome.kts | 68 - .../2016-0dc0a3e165b2c55edce38984.awesome.kts | 186 - .../2016-0ea59e1e0f84b58e26618f0e.awesome.kts | 40 - .../2016-0ff8d19eae299b390276c06e.awesome.kts | 161 - .../2016-1082409b8060514f49289d33.awesome.kts | 27 - .../2016-150bc21134f535f106e66b08.awesome.kts | 94 - .../2016-171710c9aabb3929614e6560.awesome.kts | 55 - .../2016-17751f671ea70fd172df2f60.awesome.kts | 254 - .../2016-186cd90a4b50bbfe55337300.awesome.kts | 169 - .../2016-1921e416508250a97680a2e5.awesome.kts | 183 - .../2016-19e54dbc2fd88fda57144a1c.awesome.kts | 43 - .../2016-1c21a9860a24e199dfa83885.awesome.kts | 199 - .../2016-1cd4f8fd896493ae0633f628.awesome.kts | 386 - .../2016-1dd9794e1f7a731b48b14dfc.awesome.kts | 28 - .../2016-1df2465808fa7483de3c5973.awesome.kts | 46 - .../2016-1eca8cede064245b31387182.awesome.kts | 293 - .../2016-2086fdbbfac5ea60cfd1a494.awesome.kts | 142 - .../2016-23b7705664d2fb58165399cb.awesome.kts | 72 - .../2016-24de196448ba573dc4f9dbfa.awesome.kts | 390 - .../2016-263cdeaae09d1eb2d85cd450.awesome.kts | 50 - .../2016-26446d09448076aec6a5728c.awesome.kts | 48 - .../2016-28cc676b5006aaebd64a918c.awesome.kts | 300 - .../2016-2bb27a6a36647d2a1cd465a7.awesome.kts | 163 - .../2016-2be0dd6beaba65c40ea65752.awesome.kts | 763 -- .../2016-2c06849d49f447b3ad2e1478.awesome.kts | 32 - .../2016-2ca92efca584f8a08e689787.awesome.kts | 191 - .../2016-2caca33c9d8ace18743e51e4.awesome.kts | 119 - .../2016-2cd3ded1b96e98db2b21e927.awesome.kts | 294 - .../2016-2e1dbd77c93367ee579e5148.awesome.kts | 117 - .../2016-2f376f45a35f3a6f1e338a92.awesome.kts | 93 - .../2016-30199f6c963e3320522cc1cf.awesome.kts | 31 - .../2016-31187810bf5acedd398fbf79.awesome.kts | 307 - .../2016-336105aa8e547a9ff1e3b57e.awesome.kts | 246 - .../2016-3471005a80876027458b8f92.awesome.kts | 138 - .../2016-35c625dee068c0b1f794180c.awesome.kts | 229 - .../2016-36ec23459c6bf8b8bc759f3f.awesome.kts | 68 - .../2016-38bc6954835b269270362118.awesome.kts | 91 - .../2016-394ae1494abaea321bcd5f9a.awesome.kts | 63 - .../2016-39e4ad67f25e4a709fcf8c87.awesome.kts | 54 - .../2016-3a2ff9ad40f3b56e00edd557.awesome.kts | 86 - .../2016-3a5aa1d842e7c6751456cf8d.awesome.kts | 81 - .../2016-3a5fcf143e5e848bc7b7996e.awesome.kts | 69 - .../2016-3ab6d61fc70f57a2d40513aa.awesome.kts | 22 - .../2016-3b9081ba7ea6c0396e5f81b1.awesome.kts | 62 - .../2016-3c5ebd759148c39f151c080a.awesome.kts | 29 - .../2016-3c877390446cd36d22c5879d.awesome.kts | 90 - .../2016-3d3215ed5fbef44ba72736f4.awesome.kts | 249 - .../2016-4255d0011abd9a1d037e3bac.awesome.kts | 396 - .../2016-42c0c5dc0da3dd622d346b04.awesome.kts | 68 - .../2016-42d48c9778b93c914a0c748e.awesome.kts | 114 - .../2016-42dbe436846341e58165e969.awesome.kts | 43 - .../2016-431cd2b53e4b87af63c6536a.awesome.kts | 199 - .../2016-43287111c29e26b28014534d.awesome.kts | 104 - .../2016-445010237e59c20cda51753f.awesome.kts | 62 - .../2016-46bc8b61bfa938b11d5aeff3.awesome.kts | 316 - .../2016-4a78dcc3104bc63fd564f0c7.awesome.kts | 26 - .../2016-4a9ac0dcb3b751519f981223.awesome.kts | 213 - .../2016-4bb4c8661f3d63ca3f96cf26.awesome.kts | 172 - .../2016-4be93fb1b02fec72a1479d6a.awesome.kts | 48 - .../2016-4bf9a8ee2bf6cf60317c14b7.awesome.kts | 30 - .../2016-4e28fdf6ba991d35423aee70.awesome.kts | 111 - .../2016-5115913c9d7f459ff66f9db3.awesome.kts | 320 - .../2016-521bde91b0fbf61797491770.awesome.kts | 125 - .../2016-526eefda5c77b656004c50a5.awesome.kts | 121 - .../2016-52e4f25163c33faf05aeebcb.awesome.kts | 26 - .../2016-535e4b63224ab68305384943.awesome.kts | 27 - .../2016-550b8c318b6276a5cb786448.awesome.kts | 378 - .../2016-5698768849f64ad5815c7e4b.awesome.kts | 83 - .../2016-5763a68e9736b0496e5c8113.awesome.kts | 133 - .../2016-57db3517f35bbd8048005e74.awesome.kts | 98 - .../2016-5a74f6cafe19ecbc9f86b89d.awesome.kts | 196 - .../2016-5c31f93b944c089bf1641e11.awesome.kts | 308 - .../2016-5d4af8c65e1a823fefc45e19.awesome.kts | 837 -- .../2016-5df0379e0350226db4123c19.awesome.kts | 68 - .../2016-5e88df04de910b5dd829c468.awesome.kts | 141 - .../2016-5ec1b6f5bf821f50de0bd335.awesome.kts | 57 - .../2016-5fc3f6c9609be18717946798.awesome.kts | 179 - .../2016-602c78d41f320f3595a8259b.awesome.kts | 167 - .../2016-6131a140d09a3a8ec83ad1ff.awesome.kts | 151 - .../2016-627aacdb3d340bbf878a4278.awesome.kts | 118 - .../2016-64e869d3abea5e4867bfe2df.awesome.kts | 212 - .../2016-650dd4cc4b0da798638f69f6.awesome.kts | 209 - .../2016-65f7d13a8eb71cc821ce3455.awesome.kts | 202 - .../2016-68ceb945bb0381441a588ced.awesome.kts | 180 - .../2016-68f27b2fbbb4ca118b011699.awesome.kts | 504 -- .../2016-68f58e9d99eab57c5347d7ed.awesome.kts | 116 - .../2016-693970ae59d1fe2650044308.awesome.kts | 31 - .../2016-693ac2cb019180827c2e3e2c.awesome.kts | 407 - .../2016-69a156e2bbb885ec402a1dcb.awesome.kts | 69 - .../2016-6ac2bf442514bb4883d4d99c.awesome.kts | 25 - .../2016-6bceef2cd285810a50be8e75.awesome.kts | 100 - .../2016-6c7171a62ab893ea5d2e8e92.awesome.kts | 45 - .../2016-6ca6077a7ae2335e81fdfa5b.awesome.kts | 146 - .../2016-6caed4bbf5f5d5314cf61981.awesome.kts | 119 - .../2016-6efac316422ce36e824ece9e.awesome.kts | 47 - .../2016-709a075cf11ecb6d66360279.awesome.kts | 98 - .../2016-71753534bd01f6b3825d40e8.awesome.kts | 77 - .../2016-73decb131be4e2fd04536d0e.awesome.kts | 139 - .../2016-75b036f1e4f57bc926e246e3.awesome.kts | 24 - .../2016-75f6af728f701003e4aa71db.awesome.kts | 83 - .../2016-7687a8224129a8d0b1d71107.awesome.kts | 26 - .../2016-77d3cbd423477d558763ac8d.awesome.kts | 111 - .../2016-799f92203cb8cdd6ce2c41a2.awesome.kts | 70 - .../2016-7c2a676ce11cc26b5bedd5b3.awesome.kts | 112 - .../2016-7d056606015a7df3ce5df2dc.awesome.kts | 112 - .../2016-7dd5994ebc729a04f3343fc3.awesome.kts | 39 - .../2016-7f349c80a1451da5f02992be.awesome.kts | 146 - .../2016-7f3ec77668d385906bed0947.awesome.kts | 193 - .../2016-7f79a7582fb19ca8467ca38c.awesome.kts | 348 - .../2016-7fc0816b244c3dce076f60b8.awesome.kts | 101 - .../2016-810797be34edb6b4dbd523dd.awesome.kts | 42 - .../2016-8261cd1f143a31a1d6f98255.awesome.kts | 172 - .../2016-833cee9b17227db925b4f3cc.awesome.kts | 28 - .../2016-835a73611dcac42a9fdf07a2.awesome.kts | 178 - .../2016-843be12f18c6c9882fe77d0e.awesome.kts | 30 - .../2016-844670a7df369c6438fb380a.awesome.kts | 165 - .../2016-84fe8eb2230f7a340e89ee70.awesome.kts | 143 - .../2016-85180ff477f05011282f9be3.awesome.kts | 62 - .../2016-85f92ecc92688392132a157c.awesome.kts | 119 - .../2016-863ac14f478bdfbce79e919b.awesome.kts | 48 - .../2016-876cca938ee0af6f010f1593.awesome.kts | 195 - .../2016-88b56901143b40a8a9cc20c3.awesome.kts | 298 - .../2016-895451b37b386516d9f2da01.awesome.kts | 37 - .../2016-89644d98c7d2007da5af6d89.awesome.kts | 57 - .../2016-8b31b17925b3f3447ba91137.awesome.kts | 120 - .../2016-8bba940f8bbf96c5979c4e30.awesome.kts | 96 - .../2016-8c0aade7a6e73ac737cfcc3e.awesome.kts | 216 - .../2016-8f42bb4eebaaff08579becd7.awesome.kts | 421 - .../2016-8f8b62f4e486d7127172f768.awesome.kts | 221 - .../2016-8fb12953b1b146c2aa3c12a9.awesome.kts | 710 -- .../2016-921877edeadfeddfb29ba857.awesome.kts | 168 - .../2016-93c95fb8ca4bb0937590e3cb.awesome.kts | 84 - .../2016-93f0eef7ff14099256b10c34.awesome.kts | 149 - .../2016-942a2e24c740bbd824880e2f.awesome.kts | 24 - .../2016-948f7365af30de3f7245e6db.awesome.kts | 438 - .../2016-95cfbac30b2c64a62e6774e9.awesome.kts | 101 - .../2016-96aa9f29f55ec2d8c92b3b94.awesome.kts | 83 - .../2016-96c57789390db765cddc1be9.awesome.kts | 76 - .../2016-96f2e54594c534c2555819c6.awesome.kts | 111 - .../2016-977fbdc6e922ff62e9e9400a.awesome.kts | 62 - .../2016-98937645073d24a2f48bfc41.awesome.kts | 57 - .../2016-9b1a52c2b0880e3842a267b1.awesome.kts | 58 - .../2016-9c5c384f05d7f31a6e358b1b.awesome.kts | 63 - .../2016-9db18b46178528ce1a403ea9.awesome.kts | 89 - .../2016-9f30dd7283f90d50dc9a3d1e.awesome.kts | 88 - .../2016-a0c3367fff4406be12a7a110.awesome.kts | 151 - .../2016-a171e4515c73ed8413c9849b.awesome.kts | 40 - .../2016-a1ba51190e8b6e9eb7fe97d2.awesome.kts | 26 - .../2016-a20729d546b03752baa768bc.awesome.kts | 117 - .../2016-a210e5967b6f195bb5b8b436.awesome.kts | 24 - .../2016-a2a546cc6730a821f5dc4236.awesome.kts | 32 - .../2016-a33d5f69f7e730c614535d0d.awesome.kts | 165 - .../2016-a3c2d7d8dfdc076ce7fc084a.awesome.kts | 182 - .../2016-a489989c4509a072783d5415.awesome.kts | 91 - .../2016-a4ef66835a28eb0cd4216f9e.awesome.kts | 168 - .../2016-a58012e1cd6d4728f93f942c.awesome.kts | 454 - .../2016-a9056ccf26b3b2285837afe6.awesome.kts | 250 - .../2016-a97664dd23b685690e8c99f5.awesome.kts | 26 - .../2016-aa228bbd646683765bba8a05.awesome.kts | 90 - .../2016-aa44a938de92a1476940ff4a.awesome.kts | 36 - .../2016-ace00c882586674e12b170ba.awesome.kts | 294 - .../2016-af945df7eb11118cd174d958.awesome.kts | 84 - .../2016-b014b49018b0dc6a8f9fc1fb.awesome.kts | 137 - .../2016-b04fa09578d1585c9bf6a8b5.awesome.kts | 299 - .../2016-b05d9deb1d58134bf0de1cfe.awesome.kts | 77 - .../2016-b119f5a861ef4335d5e13eb1.awesome.kts | 155 - .../2016-b13ba4d768f9af6e28c7b635.awesome.kts | 43 - .../2016-b405f88ac956f7d86513b77a.awesome.kts | 219 - .../2016-b6033ea3b43f2f5719fa4074.awesome.kts | 150 - .../2016-b6689772aa5900d935b245b8.awesome.kts | 73 - .../2016-b737f02ad34d6d02f9065ff1.awesome.kts | 121 - .../2016-b7d94770fa283965d36edb4e.awesome.kts | 39 - .../2016-b971195fda09015a993e97ac.awesome.kts | 655 -- .../2016-b97fc8f25d9e0b63e40a8eed.awesome.kts | 121 - .../2016-ba727eeeabedc8ef3055f836.awesome.kts | 127 - .../2016-bb84aba446e7533a023e7787.awesome.kts | 29 - .../2016-bcf2a5cfb216a3bd6c94b179.awesome.kts | 43 - .../2016-bf89a524fe044a02fbec70e3.awesome.kts | 138 - .../2016-c0f49c8bcd5a444cbffc630c.awesome.kts | 87 - .../2016-c135ec1b836b866eb8ef5ffd.awesome.kts | 82 - .../2016-c210d58e4ab39ac951453ecf.awesome.kts | 27 - .../2016-c49ea29a4cf7dd51f954b1b5.awesome.kts | 226 - .../2016-c52161aa4c5732511e2eceab.awesome.kts | 128 - .../2016-cad6310e3645a04e011a4a98.awesome.kts | 29 - .../2016-cc4f6de957d37f66b0bbfd99.awesome.kts | 26 - .../2016-ce30221c54569430212817f9.awesome.kts | 65 - .../2016-cf3c017775469362dff43711.awesome.kts | 26 - .../2016-cfadd5dd77d4539669f6fd63.awesome.kts | 134 - .../2016-cfbf0585c22d63e27d96cd1c.awesome.kts | 69 - .../2016-d1e76e4f9af8b3e921c2173d.awesome.kts | 25 - .../2016-d27fb35714a50d4f8e8bd4ec.awesome.kts | 54 - .../2016-d72e078fcaf908c01f8cfd5d.awesome.kts | 131 - .../2016-d77af2564744b28f6dc3438b.awesome.kts | 27 - .../2016-d8438acc1948008d644e8b31.awesome.kts | 178 - .../2016-d8c8031bf2f944833a3d1bd3.awesome.kts | 75 - .../2016-d985e297a518cf1f818682ed.awesome.kts | 26 - .../2016-dc0f7d9d0f146696fada182f.awesome.kts | 231 - .../2016-dcc6a34e3894b6061b7c265e.awesome.kts | 95 - .../2016-dcdeeb41ff3e4dcf21bd9d53.awesome.kts | 81 - .../2016-dd0954e9a90b6c7d52e48f70.awesome.kts | 66 - .../2016-ddcbd4c945e89c72618c5e7c.awesome.kts | 58 - .../2016-de238a388570dd0ecdb72266.awesome.kts | 107 - .../2016-deca01d6cd8229c7934d5efc.awesome.kts | 58 - .../2016-e12dc1675e54642217216764.awesome.kts | 75 - .../2016-e12ef899063e57c86f2127ed.awesome.kts | 109 - .../2016-e15acecb122529580b029541.awesome.kts | 103 - .../2016-e1915d975fb3922b38bbdc7c.awesome.kts | 123 - .../2016-e1ec3da29327450d9db288e1.awesome.kts | 202 - .../2016-e4b28497862014c8fc54b28a.awesome.kts | 46 - .../2016-e51ccecd8b58ea38d9a4d587.awesome.kts | 88 - .../2016-e64c00166e68889e640210c7.awesome.kts | 352 - .../2016-e67d39fec1b4e33636615edb.awesome.kts | 93 - .../2016-e70073bcff0ea2bf1616eb71.awesome.kts | 273 - .../2016-eb4ad759de0aeb7152acd4de.awesome.kts | 174 - .../2016-ec4ada3f896d6582c993ec72.awesome.kts | 247 - .../2016-edfab15e3a91965c5f200d34.awesome.kts | 209 - .../2016-f08cee1f3e73a2c99afe98cb.awesome.kts | 50 - .../2016-f0c2aaa9cf1991ea2ce10fff.awesome.kts | 217 - .../2016-f3a0a6bc82694103ae2fb93a.awesome.kts | 69 - .../2016-f6716af4bb8b1242e1bb13fc.awesome.kts | 339 - .../2016-f7b489a06940f46a1a3ca938.awesome.kts | 46 - .../2016-f901c99406a0d7d75401f639.awesome.kts | 84 - .../2016-fb23003416802ad89073be4b.awesome.kts | 35 - .../2016-fd42b2f2f7ed8318533011bb.awesome.kts | 581 -- .../2016-fdd73548da8519c947637a45.awesome.kts | 169 - .../2016-ff626f84ee081bb09fabd20a.awesome.kts | 92 - .../2016-ff8f29fdae0a2726f72be996.awesome.kts | 125 - .../2017-02e680cba3e75ff13ec593b4.awesome.kts | 40 - .../2017-0669d1750e756995be758d82.awesome.kts | 174 - .../2017-06f1a06fc5158e2abab26aa6.awesome.kts | 278 - .../2017-14f430dfbde488d5f9ac5d6d.awesome.kts | 48 - .../2017-18a29f8d330211ffd29ac36c.awesome.kts | 221 - .../2017-2de67c200ee1243e75c329d6.awesome.kts | 137 - .../2017-3541606739ef99cc9edb185f.awesome.kts | 174 - .../2017-36d30408aafc38ff1dfb0c4e.awesome.kts | 533 -- .../2017-39ab27c5cda7750996cf385b.awesome.kts | 193 - .../2017-3c0f1cb6210fcaf6961c9540.awesome.kts | 39 - .../2017-3c9c0e34f73569ac0fb2a07c.awesome.kts | 40 - .../2017-4b1bf8ddff136175396ca0af.awesome.kts | 37 - .../2017-50e184a426915a5aae38e2f5.awesome.kts | 147 - .../2017-55bf98f5ebb96a3fc0fbc947.awesome.kts | 23 - .../2017-79f41dfc1fdb148e0f82706d.awesome.kts | 45 - .../2017-7baeda53dff17ac99bf6aa42.awesome.kts | 148 - .../2017-7bc151aee76654415d4fd1ab.awesome.kts | 240 - .../2017-7dbfec506fbf710ddeba3472.awesome.kts | 27 - .../2017-7dde9a7a53fff296313c82d3.awesome.kts | 75 - .../2017-8695bcc02c025a816551d473.awesome.kts | 248 - .../2017-8bbafa401c91ca8e167c0ace.awesome.kts | 72 - .../2017-916b3924483991f3fac093b0.awesome.kts | 93 - .../2017-9faf0eb63cc2cf86f9ca63b9.awesome.kts | 52 - .../2017-a232bc9e6c7e3ce4cfe83f0a.awesome.kts | 80 - .../2017-a2d8ca8f90a29ec65026578a.awesome.kts | 49 - .../2017-ab514289ea34d74fe01126a3.awesome.kts | 223 - .../2017-af0e236ef5ef906ac97df42d.awesome.kts | 184 - .../2017-bf845594530a25b4df848ccb.awesome.kts | 165 - .../2017-c063076c586c25b77a7c5b21.awesome.kts | 58 - .../2017-cd6421f7c3f0c6c08cc2107d.awesome.kts | 95 - .../2017-cdf5798e392c1d05c6dd08f2.awesome.kts | 174 - .../2017-d5127ac07a4c323b952dadcd.awesome.kts | 62 - .../2017-d54741b69c8e4ca7cb6d42a4.awesome.kts | 32 - .../2017-da12f95f1a2cb71cfa573022.awesome.kts | 294 - .../2017-dcb512e6b77bb34b75da58c7.awesome.kts | 42 - .../2017-e740bf420b3627bdf5ea3c10.awesome.kts | 98 - .../2017-f1453f1437c28abbd68d16af.awesome.kts | 32 - .../2017-f2681159467e3cb3ebedab94.awesome.kts | 126 - .../2017-f9874d2b61dd799265dede6b.awesome.kts | 50 - .../2018-11bc85488320be64f72e6fec.awesome.kts | 40 - build.gradle.kts | 60 - gradle/libs.versions.toml | 2 +- readme/LICENSE | 121 - .../kotlin/link/kotlin/scripts/Application.kt | 18 - .../link/kotlin/scripts/ApplicationModule.kt | 143 - .../link/kotlin/scripts/ArticlesSource.kt | 40 - .../kotlin/scripts/AwesomeKotlinGenerator.kt | 43 - .../link/kotlin/scripts/CategoryProcessor.kt | 38 - .../kotlin/scripts/KotlinVersionFetcher.kt | 63 - .../link/kotlin/scripts/LinksChecker.kt | 39 - .../kotlin/link/kotlin/scripts/LinksSource.kt | 54 - .../link/kotlin/scripts/MarkdownRenderer.kt | 33 - .../link/kotlin/scripts/SiteGenerator.kt | 95 - .../link/kotlin/scripts/SitemapGenerator.kt | 18 - .../kotlin/link/kotlin/scripts/dsl/DSL.kt | 150 - .../link/kotlin/scripts/import/Communities.kt | 91 - .../link/kotlin/scripts/import/Readability.kt | 101 - .../kotlin/scripts/import/user-group-list.md | 230 - .../scripts/model/ApplicationConfiguration.kt | 33 - .../kotlin/link/kotlin/scripts/model/Dto.kt | 70 - .../kotlin/link/kotlin/scripts/model/Link.kt | 22 - .../kotlin/scripts/scripting/AwesomeScript.kt | 40 - .../scripts/scripting/ScriptEvaluator.kt | 57 - .../kotlin/link/kotlin/scripts/utils/Cache.kt | 86 - .../link/kotlin/scripts/utils/CopyTask.kt | 11 - .../kotlin/link/kotlin/scripts/utils/Fs.kt | 24 - .../link/kotlin/scripts/utils/HttpClient.kt | 75 - .../kotlin/link/kotlin/scripts/utils/Utils.kt | 62 - ....scripts.scripting.AwesomeScript.classname | 0 src/main/resources/links/Android.awesome.kts | 755 -- src/main/resources/links/Archive.awesome.kts | 78 - .../resources/links/JavaScript.awesome.kts | 115 - .../resources/links/Libraries.awesome.kts | 2417 ------ src/main/resources/links/Links.awesome.kts | 373 - src/main/resources/links/Native.awesome.kts | 35 - src/main/resources/links/Projects.awesome.kts | 518 -- .../resources/links/UserGroups.awesome.kts | 1257 --- .../resources/links/WebAssembly.awesome.kts | 20 - src/main/resources/logback.xml | 11 - .../kotlin/scripts/ReadmeGeneratorTest.kt | 14 - .../scripts/VersionFetcherManualTest.kt | 11 - .../kotlin/scripts/utils/ParseInstantTest.kt | 12 - 1114 files changed, 7861 insertions(+), 75056 deletions(-) delete mode 100644 .run/Awesome Kotlin 1.0.run.xml delete mode 100644 app-backend/Dockerfile create mode 100644 app-backend/api-resources.http create mode 100644 app-backend/src/main/kotlin/ApplicationModule.kt delete mode 100644 app-backend/src/main/kotlin/ConfigModule.kt delete mode 100644 app-backend/src/main/kotlin/FlywayModule.kt delete mode 100644 app-backend/src/main/kotlin/HttpClientModule.kt delete mode 100644 app-backend/src/main/kotlin/LifecycleModule.kt delete mode 100644 app-backend/src/main/kotlin/MetricsModule.kt delete mode 100644 app-backend/src/main/kotlin/ServerModule.kt delete mode 100644 app-backend/src/main/kotlin/XmlModule.kt delete mode 100644 app-backend/src/main/kotlin/YamlModule.kt delete mode 100644 app-backend/src/main/kotlin/config/dotenv.kt create mode 100644 app-backend/src/main/kotlin/infra/HttpClientModule.kt create mode 100644 app-backend/src/main/kotlin/infra/cache/CacheBuilder.kt create mode 100644 app-backend/src/main/kotlin/infra/cache/LoadingCache.kt create mode 100644 app-backend/src/main/kotlin/infra/cache/SimpleLoadingCache.kt create mode 100644 app-backend/src/main/kotlin/infra/config/ConfigModule.kt create mode 100644 app-backend/src/main/kotlin/infra/db/FlywayModule.kt rename app-backend/src/main/kotlin/{ => infra/db}/JdbcModule.kt (54%) rename app-backend/src/main/kotlin/{ => infra/db}/JooqModule.kt (59%) create mode 100644 app-backend/src/main/kotlin/infra/file_watcher/FileMonitor.kt create mode 100644 app-backend/src/main/kotlin/infra/file_watcher/FileMonitorModule.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/KtorFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/KtorFeaturesModule.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/KtorRoute.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/AuthenticationFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/CachingFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/CallLoggingFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/ContentNegotiationFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/MetricsFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/ResourcesFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/StatusPageFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/ktor/features/WebSocketsFeature.kt create mode 100644 app-backend/src/main/kotlin/infra/lifecycle/AutoClosableModule.kt rename app-backend/src/main/kotlin/{ => infra}/lifecycle/GracefulShutdown.kt (91%) create mode 100644 app-backend/src/main/kotlin/infra/lifecycle/LifecycleModule.kt rename app-backend/src/main/kotlin/{ => infra}/lifecycle/ShutdownManager.kt (87%) create mode 100644 app-backend/src/main/kotlin/infra/metrics/MetricsModule.kt create mode 100644 app-backend/src/main/kotlin/infra/metrics/MetricsRoute.kt rename app-backend/src/main/kotlin/{ => infra}/serialization/TimeSerializers.kt (98%) create mode 100644 app-backend/src/main/kotlin/infra/serialization/XmlModule.kt create mode 100644 app-backend/src/main/kotlin/infra/serialization/YamlModule.kt rename app-backend/src/main/kotlin/{ => infra}/utils/collections.kt (84%) create mode 100644 app-backend/src/main/kotlin/jooq/main/tables/GithubAuth.kt create mode 100644 app-backend/src/main/kotlin/jooq/main/tables/daos/GithubAuthDao.kt create mode 100644 app-backend/src/main/kotlin/jooq/main/tables/pojos/GithubAuth.kt create mode 100644 app-backend/src/main/kotlin/jooq/main/tables/records/GithubAuthRecord.kt delete mode 100644 app-backend/src/main/kotlin/ktor/KtorRoute.kt delete mode 100644 app-backend/src/main/kotlin/ktor/plugins/HTTP.kt delete mode 100644 app-backend/src/main/kotlin/ktor/plugins/Monitoring.kt delete mode 100644 app-backend/src/main/kotlin/ktor/plugins/Sockets.kt delete mode 100644 app-backend/src/main/kotlin/model/KotlinPlatform.kt delete mode 100644 app-backend/src/main/kotlin/model/KotlinVersion.kt delete mode 100644 app-backend/src/main/kotlin/model/Language.kt create mode 100644 app-backend/src/main/kotlin/server/KtorRoutesModule.kt create mode 100644 app-backend/src/main/kotlin/server/KtorServerModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/articles/ArticleSource.kt create mode 100644 app-backend/src/main/kotlin/usecases/articles/ArticlesModule.kt rename {src/main/kotlin/link/kotlin/scripts => app-backend/src/main/kotlin/usecases/articles}/ArticlesProcessor.kt (79%) create mode 100644 app-backend/src/main/kotlin/usecases/articles/MarkdownRenderer.kt rename {src/main/kotlin/link/kotlin/scripts => app-backend/src/main/kotlin/usecases/articles}/PagesGenerator.kt (60%) create mode 100644 app-backend/src/main/kotlin/usecases/github_trending/GithubConfig.kt rename src/main/kotlin/link/kotlin/scripts/GithubTrending.kt => app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSource.kt (54%) create mode 100644 app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSourceModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/healthcheck/HealthCheckRoute.kt create mode 100644 app-backend/src/main/kotlin/usecases/healthcheck/HealthcheckModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/links/CategoryProcessor.kt create mode 100644 app-backend/src/main/kotlin/usecases/links/LinkSourceModel.kt delete mode 100644 app-backend/src/main/kotlin/usecases/links/Links.kt create mode 100644 app-backend/src/main/kotlin/usecases/links/LinksChecker.kt create mode 100644 app-backend/src/main/kotlin/usecases/links/LinksDtoSource.kt create mode 100644 app-backend/src/main/kotlin/usecases/links/LinksModule.kt rename {src/main/kotlin/link/kotlin/scripts => app-backend/src/main/kotlin/usecases/links}/LinksProcessor.kt (59%) create mode 100644 app-backend/src/main/kotlin/usecases/links/LinksRoute.kt create mode 100644 app-backend/src/main/kotlin/usecases/links/LinksSource.kt create mode 100644 app-backend/src/main/kotlin/usecases/links/LinksV1Model.kt delete mode 100644 app-backend/src/main/kotlin/usecases/ping/Ping.kt delete mode 100644 app-backend/src/main/kotlin/usecases/ping/PingModule.kt rename {src/main/kotlin/link/kotlin/scripts => app-backend/src/main/kotlin/usecases/readme}/ReadmeGenerator.kt (97%) create mode 100644 app-backend/src/main/kotlin/usecases/readme/ReadmeModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/readme/ReadmeRoute.kt create mode 100644 app-backend/src/main/kotlin/usecases/reload/LiveReloadModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/reload/LiveReloadService.kt create mode 100644 app-backend/src/main/kotlin/usecases/reload/NotificationChannel.kt create mode 100644 app-backend/src/main/kotlin/usecases/reload/NotificationChannelModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtRoute.kt rename {src/main/kotlin/link/kotlin/scripts => app-backend/src/main/kotlin/usecases/rss}/RssGenerator.kt (83%) create mode 100644 app-backend/src/main/kotlin/usecases/rss/RssModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/rss/RssRoute.kt rename {src/main/kotlin/link/kotlin/scripts => app-backend/src/main/kotlin/usecases/sitemap}/Sitemap.kt (96%) create mode 100644 app-backend/src/main/kotlin/usecases/sitemap/SitemapGenerator.kt create mode 100644 app-backend/src/main/kotlin/usecases/sitemap/SitemapModule.kt create mode 100644 app-backend/src/main/kotlin/usecases/sitemap/SitemapRoute.kt create mode 100644 app-backend/src/main/kotlin/usecases/stars_job/StarsJob.kt create mode 100644 app-backend/src/main/kotlin/usecases/version/KotlinVersionRoute.kt create mode 100644 app-backend/src/main/kotlin/usecases/version/MavenModel.kt create mode 100644 app-backend/src/main/kotlin/usecases/web/DeploymentContext.kt create mode 100644 app-backend/src/main/kotlin/usecases/web/WebApplicationContext.kt create mode 100644 app-backend/src/main/kotlin/usecases/web/WebModule.kt delete mode 100644 app-backend/src/main/kotlin/utils/closeable.kt delete mode 100644 app-backend/src/main/kotlin/utils/logging.kt create mode 100644 app-backend/src/main/resources/data/articles.json create mode 100644 app-backend/src/main/resources/data/links.json create mode 100644 app-backend/src/main/resources/infra/db/migration/main/V1__auth.sql rename app-backend/src/main/resources/{ => infra}/db/migration/main/V20221213__init.sql (100%) delete mode 100644 app-backend/src/main/resources/links/Android.json delete mode 100644 app-backend/src/main/resources/links/Archive.json delete mode 100644 app-backend/src/main/resources/links/JavaScript.json delete mode 100644 app-backend/src/main/resources/links/Libraries.json delete mode 100644 app-backend/src/main/resources/links/Links.json delete mode 100644 app-backend/src/main/resources/links/Native.json delete mode 100644 app-backend/src/main/resources/links/Projects.json delete mode 100644 app-backend/src/main/resources/links/UserGroups.json delete mode 100644 app-backend/src/test/kotlin/di/BeanMockk.kt create mode 100644 app-backend/src/test/kotlin/types/IntegrationTest.kt create mode 100644 app-backend/src/test/kotlin/types/UnitTest.kt create mode 100644 app-backend/src/test/kotlin/usecases/robots_txt/RobotsTxtRouteTest.kt create mode 100644 app-backend/src/test/kotlin/usecases/version/MavenCentralKotlinVersionFetcherTest.kt delete mode 100644 app-frontend/.yarn/cache/@babel-code-frame-npm-7.15.8-c1e84dfd13-d75950f0e0.zip delete mode 100644 app-frontend/.yarn/cache/@babel-helper-validator-identifier-npm-7.15.7-a8f354e738-50aad8bc14.zip delete mode 100644 app-frontend/.yarn/cache/@babel-highlight-npm-7.14.5-4a18106cbc-4e4b22fb88.zip delete mode 100644 app-frontend/.yarn/cache/@gar-promisify-npm-1.1.2-2343f94380-d05081e088.zip create mode 100644 app-frontend/.yarn/cache/@isaacs-cliui-npm-8.0.2-f4364666d5-e9ed5fd27c.zip create mode 100644 app-frontend/.yarn/cache/@isaacs-fs-minipass-npm-4.0.1-677026e841-4412e9e671.zip create mode 100644 app-frontend/.yarn/cache/@jest-schemas-npm-29.6.3-292730e442-910040425f.zip create mode 100644 app-frontend/.yarn/cache/@jest-types-npm-29.6.3-a584ca999d-f74bf512fd.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-gen-mapping-npm-0.3.2-c64eeb4a4e-7ba0070be1.zip create mode 100644 app-frontend/.yarn/cache/@jridgewell-gen-mapping-npm-0.3.8-647be6e286-9d3a56ab36.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-resolve-uri-npm-3.1.0-6ff2351e61-320ceb37af.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-resolve-uri-npm-3.1.1-aa2de3f210-64d59df8ae.zip create mode 100644 app-frontend/.yarn/cache/@jridgewell-resolve-uri-npm-3.1.2-5bc4245992-97106439d7.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-set-array-npm-1.1.2-45b82d7fb6-69a84d5980.zip create mode 100644 app-frontend/.yarn/cache/@jridgewell-set-array-npm-1.2.1-2312928209-832e513a85.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-source-map-npm-0.3.2-6fd1f37b22-1aaa42075b.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-source-map-npm-0.3.5-9f964eaf44-73838ac432.zip create mode 100644 app-frontend/.yarn/cache/@jridgewell-source-map-npm-0.3.6-fe0849eb05-0a9aca9320.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-sourcemap-codec-npm-1.4.14-f5f0630788-26e768fae6.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-sourcemap-codec-npm-1.4.15-a055fb62cf-89960ac087.zip create mode 100644 app-frontend/.yarn/cache/@jridgewell-sourcemap-codec-npm-1.5.0-dfd9126d71-4ed6123217.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-trace-mapping-npm-0.3.17-57578fd48c-790d439c9b.zip delete mode 100644 app-frontend/.yarn/cache/@jridgewell-trace-mapping-npm-0.3.22-0baba2f798-48d3e3db00.zip create mode 100644 app-frontend/.yarn/cache/@jridgewell-trace-mapping-npm-0.3.25-c076fd2279-dced32160a.zip delete mode 100644 app-frontend/.yarn/cache/@leichtgewicht-ip-codec-npm-2.0.4-dd4d657af8-3c7ffb0afb.zip create mode 100644 app-frontend/.yarn/cache/@npmcli-agent-npm-3.0.0-169e79294f-775c9a7eb1.zip delete mode 100644 app-frontend/.yarn/cache/@npmcli-fs-npm-1.0.0-92194475f3-3f93c1d9a8.zip create mode 100644 app-frontend/.yarn/cache/@npmcli-fs-npm-4.0.0-1d9cc8a27b-405c4490e1.zip delete mode 100644 app-frontend/.yarn/cache/@npmcli-move-file-npm-1.1.2-4f6c7b3354-c96381d4a3.zip create mode 100644 app-frontend/.yarn/cache/@parcel-watcher-darwin-arm64-npm-2.5.0-4eab519184-10.zip create mode 100644 app-frontend/.yarn/cache/@parcel-watcher-npm-2.5.0-f36bd41c3b-1e28b1aa9a.zip create mode 100644 app-frontend/.yarn/cache/@pkgjs-parseargs-npm-0.11.0-cd2a3fe948-115e8ceeec.zip create mode 100644 app-frontend/.yarn/cache/@sinclair-typebox-npm-0.27.8-23e206d653-297f95ff77.zip delete mode 100644 app-frontend/.yarn/cache/@sindresorhus-merge-streams-npm-1.0.0-2ae6684f8f-453c2a2816.zip create mode 100644 app-frontend/.yarn/cache/@sindresorhus-merge-streams-npm-2.3.0-5d49fcd96d-798bcb53cd.zip delete mode 100644 app-frontend/.yarn/cache/@tootallnate-once-npm-1.1.2-0517220057-e1fb1bbbc1.zip create mode 100644 app-frontend/.yarn/cache/@trysound-sax-npm-0.2.0-9f763d0295-7379713eca.zip delete mode 100644 app-frontend/.yarn/cache/@types-body-parser-npm-1.19.2-f845b7b538-e17840c7d7.zip delete mode 100644 app-frontend/.yarn/cache/@types-bonjour-npm-3.5.13-6614f112a1-e827570e09.zip delete mode 100644 app-frontend/.yarn/cache/@types-connect-history-api-fallback-npm-1.5.4-c8b583432c-e1dee43b85.zip delete mode 100644 app-frontend/.yarn/cache/@types-connect-npm-3.4.35-7337eee0a3-fe81351470.zip delete mode 100644 app-frontend/.yarn/cache/@types-cookie-npm-0.6.0-1f4c3f48f0-b883348d5b.zip delete mode 100644 app-frontend/.yarn/cache/@types-express-npm-4.17.14-076e1b4711-293e53a757.zip delete mode 100644 app-frontend/.yarn/cache/@types-express-npm-4.17.21-be92a0245e-7a6d26cf6f.zip delete mode 100644 app-frontend/.yarn/cache/@types-express-serve-static-core-npm-4.17.31-846873f446-020210f32d.zip delete mode 100644 app-frontend/.yarn/cache/@types-express-serve-static-core-npm-4.17.43-9cbdf8ef01-9079e13747.zip delete mode 100644 app-frontend/.yarn/cache/@types-html-minifier-terser-npm-6.0.0-3667095d04-6680492f2a.zip create mode 100644 app-frontend/.yarn/cache/@types-html-minifier-terser-npm-6.1.0-707ea07fcb-06bb3e1e8e.zip delete mode 100644 app-frontend/.yarn/cache/@types-http-errors-npm-2.0.4-8b39ca5d7c-1f3d7c3b32.zip delete mode 100644 app-frontend/.yarn/cache/@types-http-proxy-npm-1.17.9-fa2f5ce316-48075c535a.zip create mode 100644 app-frontend/.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.6-2ea31fda9c-3feac423fd.zip create mode 100644 app-frontend/.yarn/cache/@types-istanbul-lib-report-npm-3.0.3-a5c0ef4b88-b91e9b60f8.zip create mode 100644 app-frontend/.yarn/cache/@types-istanbul-reports-npm-3.0.4-1afa69db29-93eb188357.zip delete mode 100644 app-frontend/.yarn/cache/@types-json-schema-npm-7.0.11-79462ae5ca-e50864a93f.zip delete mode 100644 app-frontend/.yarn/cache/@types-json-schema-npm-7.0.9-361918cff3-7ceb41e396.zip delete mode 100644 app-frontend/.yarn/cache/@types-mime-npm-1.3.5-48d28990db-e29a5f9c47.zip delete mode 100644 app-frontend/.yarn/cache/@types-mime-npm-3.0.1-dec03536dc-4040fac73f.zip delete mode 100644 app-frontend/.yarn/cache/@types-node-forge-npm-1.3.11-132541fb70-670c9b377c.zip delete mode 100644 app-frontend/.yarn/cache/@types-node-npm-15.14.9-739a59edff-5c9cc5346c.zip delete mode 100644 app-frontend/.yarn/cache/@types-qs-npm-6.9.7-4a3e6ca0d0-7fd6f9c250.zip delete mode 100644 app-frontend/.yarn/cache/@types-range-parser-npm-1.2.4-23d797fbde-b7c0dfd508.zip delete mode 100644 app-frontend/.yarn/cache/@types-retry-npm-0.12.2-e1f0617c50-e567503571.zip delete mode 100644 app-frontend/.yarn/cache/@types-send-npm-0.17.4-9d7c55577f-28320a2aa1.zip delete mode 100644 app-frontend/.yarn/cache/@types-serve-index-npm-1.9.4-957ae0ac38-72727c88d5.zip delete mode 100644 app-frontend/.yarn/cache/@types-serve-static-npm-1.15.0-ec80a4ac87-5f2f36a8f5.zip delete mode 100644 app-frontend/.yarn/cache/@types-serve-static-npm-1.15.5-b911ffc092-49aa21c367.zip delete mode 100644 app-frontend/.yarn/cache/@types-sockjs-npm-0.3.36-e07c2960d5-b4b5381122.zip delete mode 100644 app-frontend/.yarn/cache/@types-ws-npm-8.5.10-a877a38f71-9b414dc5e0.zip create mode 100644 app-frontend/.yarn/cache/@types-yargs-npm-17.0.33-1d6cca6a2e-16f6681bf4.zip create mode 100644 app-frontend/.yarn/cache/@types-yargs-parser-npm-21.0.3-1d265246a1-a794eb750e.zip delete mode 100644 app-frontend/.yarn/cache/abbrev-npm-1.1.1-3659247eab-2d88294118.zip create mode 100644 app-frontend/.yarn/cache/abbrev-npm-2.0.0-0eb38a17e5-ca0a54e35b.zip delete mode 100644 app-frontend/.yarn/cache/accepts-npm-1.3.7-0dc9de65aa-599aa3cc77.zip delete mode 100644 app-frontend/.yarn/cache/accepts-npm-1.3.8-9a812371c9-67eaaa90e2.zip delete mode 100644 app-frontend/.yarn/cache/acorn-npm-8.10.0-2230c9e83e-522310c20f.zip delete mode 100644 app-frontend/.yarn/cache/acorn-npm-8.8.1-20e4aea981-c77a64b3b6.zip delete mode 100644 app-frontend/.yarn/cache/agent-base-npm-6.0.2-428f325a93-21fb903e09.zip create mode 100644 app-frontend/.yarn/cache/agent-base-npm-7.1.3-b2c16e72fb-3db6d8d465.zip delete mode 100644 app-frontend/.yarn/cache/agentkeepalive-npm-4.1.4-4d5b41b4c1-848634c4e1.zip delete mode 100644 app-frontend/.yarn/cache/aggregate-error-npm-3.1.0-415a406f4e-1101a33f21.zip delete mode 100644 app-frontend/.yarn/cache/ajv-npm-8.11.2-96b35a945e-6a68106196.zip rename app-frontend/.yarn/cache/{ajv-npm-8.12.0-3bf6e30741-b406f3b79b.zip => ajv-npm-8.17.1-12ade7edc6-ee3c62162c.zip} (53%) delete mode 100644 app-frontend/.yarn/cache/ansi-html-community-npm-0.0.8-5eaef55f1b-08df369672.zip delete mode 100644 app-frontend/.yarn/cache/ansi-regex-npm-2.1.1-ddd24d102b-190abd03e4.zip create mode 100644 app-frontend/.yarn/cache/ansi-regex-npm-6.1.0-abe011aae4-495834a53b.zip delete mode 100644 app-frontend/.yarn/cache/ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip create mode 100644 app-frontend/.yarn/cache/ansi-styles-npm-6.2.1-d43647018c-70fdf883b7.zip delete mode 100644 app-frontend/.yarn/cache/anymatch-npm-3.1.2-1d5471acfa-985163db22.zip delete mode 100644 app-frontend/.yarn/cache/aproba-npm-1.2.0-34129f0778-48def77733.zip delete mode 100644 app-frontend/.yarn/cache/are-we-there-yet-npm-1.1.7-db9f39924e-5fc14ea29e.zip delete mode 100644 app-frontend/.yarn/cache/argparse-npm-2.0.1-faff7999e6-18640244e6.zip delete mode 100644 app-frontend/.yarn/cache/array-flatten-npm-1.1.1-9d94ad5f1d-e13c9d2472.zip delete mode 100644 app-frontend/.yarn/cache/autoprefixer-npm-10.4.20-dd5fd05d27-d3c4b562fc.zip delete mode 100644 app-frontend/.yarn/cache/batch-npm-0.6.1-70e2e81169-61f9934c73.zip delete mode 100644 app-frontend/.yarn/cache/binary-extensions-npm-2.2.0-180c33fec7-ccd267956c.zip delete mode 100644 app-frontend/.yarn/cache/body-parser-npm-1.20.3-c7b184cd14-8723e3d7a6.zip delete mode 100644 app-frontend/.yarn/cache/bonjour-service-npm-1.2.1-3b11acdfe6-8350d135ab.zip delete mode 100644 app-frontend/.yarn/cache/brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip create mode 100644 app-frontend/.yarn/cache/brace-expansion-npm-2.0.1-17aa2616f9-a61e7cd2e8.zip delete mode 100644 app-frontend/.yarn/cache/browserslist-npm-4.23.3-4e727c7b5b-e266d18c6c.zip rename app-frontend/.yarn/cache/{browserslist-npm-4.24.2-0bc5f13e3b-f8a9d78bba.zip => browserslist-npm-4.24.3-1f4e7bedfb-f5b2275730.zip} (84%) delete mode 100644 app-frontend/.yarn/cache/bundle-name-npm-4.1.0-4688335533-1d966c8d2d.zip delete mode 100644 app-frontend/.yarn/cache/bytes-npm-3.0.0-19be09472d-a2b386dd81.zip delete mode 100644 app-frontend/.yarn/cache/bytes-npm-3.1.2-28b8643004-a10abf2ba7.zip delete mode 100644 app-frontend/.yarn/cache/cacache-npm-15.3.0-a7e5239c6a-1432d84f3f.zip create mode 100644 app-frontend/.yarn/cache/cacache-npm-19.0.1-395cba1936-ea026b27b1.zip delete mode 100644 app-frontend/.yarn/cache/call-bind-npm-1.0.7-762763ef96-cd6fe658e0.zip delete mode 100644 app-frontend/.yarn/cache/callsites-npm-3.1.0-268f989910-072d17b6ab.zip create mode 100644 app-frontend/.yarn/cache/caniuse-api-npm-3.0.0-1272c2981e-db2a229383.zip delete mode 100644 app-frontend/.yarn/cache/caniuse-lite-npm-1.0.30001647-ad375193cb-fd2dacf26d.zip delete mode 100644 app-frontend/.yarn/cache/caniuse-lite-npm-1.0.30001677-11c12e06e9-e07439bdea.zip create mode 100644 app-frontend/.yarn/cache/caniuse-lite-npm-1.0.30001690-d600e5893e-9fb4659eb0.zip delete mode 100644 app-frontend/.yarn/cache/chalk-npm-2.4.2-3ea16dd91e-3d1d103433.zip delete mode 100644 app-frontend/.yarn/cache/chokidar-npm-3.6.0-3c413a828f-c327fb0770.zip create mode 100644 app-frontend/.yarn/cache/chokidar-npm-4.0.3-962354fbb4-bf2a575ea5.zip delete mode 100644 app-frontend/.yarn/cache/chownr-npm-2.0.0-638f1c9c61-c57cf9dd07.zip create mode 100644 app-frontend/.yarn/cache/chownr-npm-3.0.0-5275e85d25-b63cb1f73d.zip delete mode 100644 app-frontend/.yarn/cache/chrome-trace-event-npm-1.0.3-e0ae3dcd60-b5fbdae5bf.zip create mode 100644 app-frontend/.yarn/cache/chrome-trace-event-npm-1.0.4-4f22eb2c55-1762bed739.zip create mode 100644 app-frontend/.yarn/cache/ci-info-npm-3.9.0-646784ca0e-75bc67902b.zip delete mode 100644 app-frontend/.yarn/cache/clean-css-npm-5.2.2-ccb3a2a994-fd018eeb81.zip create mode 100644 app-frontend/.yarn/cache/clean-css-npm-5.3.3-d2bb553a94-2db1ae37b3.zip delete mode 100644 app-frontend/.yarn/cache/clean-stack-npm-2.2.0-a8ce435a5c-2ac8cd2b2f.zip delete mode 100644 app-frontend/.yarn/cache/code-point-at-npm-1.1.0-37de5fe566-17d5666611.zip delete mode 100644 app-frontend/.yarn/cache/color-convert-npm-1.9.3-1fe690075e-ffa3190250.zip delete mode 100644 app-frontend/.yarn/cache/color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip create mode 100644 app-frontend/.yarn/cache/colord-npm-2.9.3-5c35c27898-907a4506d7.zip delete mode 100644 app-frontend/.yarn/cache/colorette-npm-2.0.16-7b996485d7-8501db5750.zip rename app-frontend/.yarn/cache/{colorette-npm-2.0.19-f73dfe6a4e-6e2606435c.zip => colorette-npm-2.0.20-692d428726-0b8de48bfa.zip} (85%) create mode 100644 app-frontend/.yarn/cache/commander-npm-7.2.0-19178180f8-9973af1072.zip delete mode 100644 app-frontend/.yarn/cache/compressible-npm-2.0.18-ee5ab04d88-58321a85b3.zip delete mode 100644 app-frontend/.yarn/cache/compression-npm-1.7.4-e0cd6afa69-469cd09790.zip delete mode 100644 app-frontend/.yarn/cache/concat-map-npm-0.0.1-85a921b7ee-9680699c8e.zip delete mode 100644 app-frontend/.yarn/cache/connect-history-api-fallback-npm-2.0.0-27b00b1571-3b26bf4041.zip delete mode 100644 app-frontend/.yarn/cache/console-control-strings-npm-1.1.0-e3160e5275-27b5fa302b.zip delete mode 100644 app-frontend/.yarn/cache/content-disposition-npm-0.5.4-2d93678616-b7f4ce176e.zip delete mode 100644 app-frontend/.yarn/cache/content-type-npm-1.0.4-3b1a5ca16b-5ea85c5293.zip delete mode 100644 app-frontend/.yarn/cache/content-type-npm-1.0.5-3e037bf9ab-585847d98d.zip delete mode 100644 app-frontend/.yarn/cache/cookie-npm-0.7.1-f01524ff99-aec6a6aa07.zip delete mode 100644 app-frontend/.yarn/cache/cookie-npm-1.0.2-7a4273d897-f5817cdc84.zip delete mode 100644 app-frontend/.yarn/cache/cookie-signature-npm-1.0.6-93f325f7f0-f4e1b0a98a.zip delete mode 100644 app-frontend/.yarn/cache/copy-anything-npm-2.0.3-fb13168fff-ae3da717e7.zip delete mode 100644 app-frontend/.yarn/cache/core-js-npm-3.39.0-4c420e59a7-a3d34e6697.zip delete mode 100644 app-frontend/.yarn/cache/core-util-is-npm-1.0.3-ca74b76c90-9de8597363.zip delete mode 100644 app-frontend/.yarn/cache/cosmiconfig-npm-9.0.0-47d78cf275-8bdf1dfbb6.zip rename app-frontend/.yarn/cache/{cross-spawn-npm-7.0.5-cf92562a27-c95062469d.zip => cross-spawn-npm-7.0.6-264bddf921-0d52657d7a.zip} (60%) create mode 100644 app-frontend/.yarn/cache/css-declaration-sorter-npm-7.2.0-b5087e1063-2acb9c13f5.zip create mode 100644 app-frontend/.yarn/cache/css-minimizer-webpack-plugin-npm-7.0.0-f09f3109c8-47d8f8a38c.zip delete mode 100644 app-frontend/.yarn/cache/css-select-npm-4.1.3-97d7b817c1-53743b2d08.zip create mode 100644 app-frontend/.yarn/cache/css-select-npm-4.3.0-72f53028ec-8f7310c9af.zip create mode 100644 app-frontend/.yarn/cache/css-select-npm-5.1.0-9365a79de5-d486b1e7eb.zip create mode 100644 app-frontend/.yarn/cache/css-tree-npm-2.2.1-ee98ac48a8-1959c4b0e2.zip create mode 100644 app-frontend/.yarn/cache/css-tree-npm-2.3.1-6540d78e26-e5e39b82eb.zip delete mode 100644 app-frontend/.yarn/cache/css-what-npm-5.1.0-9991ae71a8-3b1f0abdf1.zip create mode 100644 app-frontend/.yarn/cache/css-what-npm-6.1.0-57f751efbb-c67a3a2d0d.zip create mode 100644 app-frontend/.yarn/cache/cssnano-npm-7.0.6-b3934f23a5-12b1e1f2b5.zip create mode 100644 app-frontend/.yarn/cache/cssnano-preset-default-npm-7.0.6-2c1cf6f352-686e7652d0.zip create mode 100644 app-frontend/.yarn/cache/cssnano-utils-npm-5.0.0-99da5e5744-89ed5b8ca5.zip create mode 100644 app-frontend/.yarn/cache/csso-npm-5.0.5-b21e2a8b65-4036fb2b9f.zip delete mode 100644 app-frontend/.yarn/cache/csstype-npm-3.0.9-0801c4a6d7-ffa22664f3.zip create mode 100644 app-frontend/.yarn/cache/csstype-npm-3.1.3-e9a1c85013-f593cce41f.zip delete mode 100644 app-frontend/.yarn/cache/debug-npm-2.6.9-7d4cb597dc-e07005f2b4.zip delete mode 100644 app-frontend/.yarn/cache/debug-npm-3.2.7-754e818c7a-d86fd7be2b.zip delete mode 100644 app-frontend/.yarn/cache/debug-npm-4.3.2-f0148b6afe-6a2980374e.zip create mode 100644 app-frontend/.yarn/cache/debug-npm-4.4.0-f6efe76023-1847944c2e.zip delete mode 100644 app-frontend/.yarn/cache/default-browser-id-npm-5.0.0-41fa64d5bb-185bfaecec.zip delete mode 100644 app-frontend/.yarn/cache/default-browser-npm-5.2.1-e2f8bca718-afab7eff7b.zip delete mode 100644 app-frontend/.yarn/cache/define-data-property-npm-1.1.4-4cbd8efc51-abdcb2505d.zip delete mode 100644 app-frontend/.yarn/cache/define-lazy-prop-npm-3.0.0-6bb0fc1510-f28421cf9e.zip delete mode 100644 app-frontend/.yarn/cache/delegates-npm-1.0.0-9b1942d75f-a51744d9b5.zip delete mode 100644 app-frontend/.yarn/cache/depd-npm-1.1.2-b0c8414da7-2ed6966fc1.zip delete mode 100644 app-frontend/.yarn/cache/depd-npm-2.0.0-b6c51a4b43-c0c8ff3607.zip delete mode 100644 app-frontend/.yarn/cache/destroy-npm-1.2.0-6a511802e2-0acb300b74.zip create mode 100644 app-frontend/.yarn/cache/detect-libc-npm-1.0.3-c30ac344d4-3849fe7720.zip delete mode 100644 app-frontend/.yarn/cache/detect-node-npm-2.1.0-e8de0e94f7-832184ec45.zip delete mode 100644 app-frontend/.yarn/cache/dns-packet-npm-5.4.0-4d0332a163-6a3827d59a.zip delete mode 100644 app-frontend/.yarn/cache/dom-serializer-npm-1.3.2-133de2b9ce-102ea83664.zip create mode 100644 app-frontend/.yarn/cache/dom-serializer-npm-1.4.1-ebb24349c1-53b217bcfe.zip create mode 100644 app-frontend/.yarn/cache/dom-serializer-npm-2.0.0-378ebc7200-e3bf9027a6.zip delete mode 100644 app-frontend/.yarn/cache/domelementtype-npm-2.2.0-c37b3b15bf-24cb386198.zip create mode 100644 app-frontend/.yarn/cache/domelementtype-npm-2.3.0-02de7cbfba-ee837a318f.zip delete mode 100644 app-frontend/.yarn/cache/domhandler-npm-4.2.2-9a6cc9317e-502cb297ba.zip create mode 100644 app-frontend/.yarn/cache/domhandler-npm-4.3.1-493539c1ca-e0d2af7403.zip create mode 100644 app-frontend/.yarn/cache/domhandler-npm-5.0.3-3ede73dc10-809b805a50.zip create mode 100644 app-frontend/.yarn/cache/domutils-npm-3.2.2-290180a284-2e08842151.zip create mode 100644 app-frontend/.yarn/cache/eastasianwidth-npm-0.2.0-c37eb16bd1-9b1d3e1bae.zip delete mode 100644 app-frontend/.yarn/cache/ee-first-npm-1.1.1-33f8535b39-1b4cac778d.zip delete mode 100644 app-frontend/.yarn/cache/electron-to-chromium-npm-1.5.4-58d50ae1f7-ce64db25c3.zip delete mode 100644 app-frontend/.yarn/cache/electron-to-chromium-npm-1.5.50-c2eeb3c362-635ca4b593.zip create mode 100644 app-frontend/.yarn/cache/electron-to-chromium-npm-1.5.79-447ec14608-c5b25ba04b.zip create mode 100644 app-frontend/.yarn/cache/emoji-regex-npm-9.2.2-e6fac8d058-915acf859c.zip delete mode 100644 app-frontend/.yarn/cache/encodeurl-npm-1.0.2-f8c8454c41-e50e3d508c.zip delete mode 100644 app-frontend/.yarn/cache/encodeurl-npm-2.0.0-3660bcc92a-abf5cd51b7.zip rename app-frontend/.yarn/cache/{enhanced-resolve-npm-5.17.1-296305b69f-e8e03cb7a4.zip => enhanced-resolve-npm-5.18.0-afcf74b9eb-e88463ef97.zip} (88%) delete mode 100644 app-frontend/.yarn/cache/enhanced-resolve-npm-5.8.3-24a728966e-46e4c12380.zip create mode 100644 app-frontend/.yarn/cache/entities-npm-4.5.0-7cdb83b832-ede2a35c9b.zip delete mode 100644 app-frontend/.yarn/cache/errno-npm-0.1.8-10ebc185bf-93076ed11b.zip delete mode 100644 app-frontend/.yarn/cache/error-ex-npm-1.3.2-5654f80c0f-d547740aa2.zip delete mode 100644 app-frontend/.yarn/cache/es-define-property-npm-1.0.0-e23aa9b242-f66ece0a88.zip delete mode 100644 app-frontend/.yarn/cache/es-errors-npm-1.3.0-fda0c9b8a8-96e65d6401.zip delete mode 100644 app-frontend/.yarn/cache/es-module-lexer-npm-1.3.0-9be5e8b1c4-dee2af0966.zip create mode 100644 app-frontend/.yarn/cache/es-module-lexer-npm-1.6.0-20500c26f6-807ee7020c.zip delete mode 100644 app-frontend/.yarn/cache/escalade-npm-3.1.2-5826d31cf8-a1e07fea2f.zip delete mode 100644 app-frontend/.yarn/cache/escape-html-npm-1.0.3-376c22ee74-6213ca9ae0.zip delete mode 100644 app-frontend/.yarn/cache/escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip delete mode 100644 app-frontend/.yarn/cache/estraverse-npm-5.2.0-b2e8e36350-9740a8fa42.zip create mode 100644 app-frontend/.yarn/cache/estraverse-npm-5.3.0-03284f8f63-37cbe6e9a6.zip delete mode 100644 app-frontend/.yarn/cache/etag-npm-1.8.1-54a3b989d9-571aeb3dbe.zip delete mode 100644 app-frontend/.yarn/cache/eventemitter3-npm-4.0.7-7afcdd74ae-8030029382.zip create mode 100644 app-frontend/.yarn/cache/exponential-backoff-npm-3.1.1-04df458b30-2d9bbb6473.zip delete mode 100644 app-frontend/.yarn/cache/express-npm-4.21.2-9b3bd32250-34571c442f.zip rename app-frontend/.yarn/cache/{fast-glob-npm-3.3.2-0a8cb4f2ca-222512e931.zip => fast-glob-npm-3.3.3-2a653be532-dcc6432b26.zip} (57%) create mode 100644 app-frontend/.yarn/cache/fast-uri-npm-3.0.5-88ac8c7ad4-21bd8d523c.zip delete mode 100644 app-frontend/.yarn/cache/fastest-levenshtein-npm-1.0.12-a32b4ef51e-e1a013698d.zip create mode 100644 app-frontend/.yarn/cache/fastest-levenshtein-npm-1.0.16-192d328856-ee85d33b5c.zip delete mode 100644 app-frontend/.yarn/cache/fastq-npm-1.13.0-a45963881c-0902cb9b81.zip create mode 100644 app-frontend/.yarn/cache/fastq-npm-1.18.0-25fe4d7171-c5b501333d.zip delete mode 100644 app-frontend/.yarn/cache/faye-websocket-npm-0.11.4-1f0de76de9-22433c14c6.zip delete mode 100644 app-frontend/.yarn/cache/finalhandler-npm-1.3.1-690d7d7e6d-4babe72969.zip delete mode 100644 app-frontend/.yarn/cache/follow-redirects-npm-1.15.6-50635fe51d-70c7612c4c.zip create mode 100644 app-frontend/.yarn/cache/foreground-child-npm-3.3.0-b8be745271-e3a60480f3.zip delete mode 100644 app-frontend/.yarn/cache/forwarded-npm-0.2.0-6473dabe35-29ba9fd347.zip delete mode 100644 app-frontend/.yarn/cache/fraction.js-npm-4.3.7-c2c7e95a8e-bb5ebcdeef.zip delete mode 100644 app-frontend/.yarn/cache/fresh-npm-0.5.2-ad2bb4c0a2-64c88e489b.zip delete mode 100644 app-frontend/.yarn/cache/fs-minipass-npm-2.1.0-501ef87306-03191781e9.zip create mode 100644 app-frontend/.yarn/cache/fs-minipass-npm-3.0.3-d148d6ac19-af143246cf.zip delete mode 100644 app-frontend/.yarn/cache/fs.realpath-npm-1.0.0-c8f05d8126-e703107c28.zip delete mode 100644 app-frontend/.yarn/cache/fsevents-npm-2.3.2-a881d6ac9f-6b5b6f5692.zip delete mode 100644 app-frontend/.yarn/cache/fsevents-patch-19706e7e35-10.zip delete mode 100644 app-frontend/.yarn/cache/function-bind-npm-1.1.1-b56b322ae9-d83f296803.zip delete mode 100644 app-frontend/.yarn/cache/gauge-npm-2.7.4-2189a73529-0db20a7def.zip delete mode 100644 app-frontend/.yarn/cache/get-intrinsic-npm-1.2.4-1dad3427b2-85bbf4b234.zip create mode 100644 app-frontend/.yarn/cache/glob-npm-10.4.5-8c63175f05-698dfe1182.zip delete mode 100644 app-frontend/.yarn/cache/glob-npm-7.2.0-bb4644d239-bc78b6ea07.zip delete mode 100644 app-frontend/.yarn/cache/globby-npm-14.0.0-3bccdd5188-6e7d84bbc6.zip create mode 100644 app-frontend/.yarn/cache/globby-npm-14.0.2-28ff4422ff-67660da70f.zip delete mode 100644 app-frontend/.yarn/cache/gopd-npm-1.0.1-10c1d0b534-5fbc7ad57b.zip delete mode 100644 app-frontend/.yarn/cache/graceful-fs-npm-4.2.8-37c16fc3d3-c29f627822.zip delete mode 100644 app-frontend/.yarn/cache/handle-thing-npm-2.0.1-084baca59e-441ec98b07.zip delete mode 100644 app-frontend/.yarn/cache/has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip delete mode 100644 app-frontend/.yarn/cache/has-npm-1.0.3-b7f00631c1-a449f3185b.zip delete mode 100644 app-frontend/.yarn/cache/has-property-descriptors-npm-1.0.2-d7077d09f1-2d8c9ab8ce.zip delete mode 100644 app-frontend/.yarn/cache/has-proto-npm-1.0.3-b598da2961-0b67c2c94e.zip delete mode 100644 app-frontend/.yarn/cache/has-symbols-npm-1.0.3-1986bff2c4-464f97a820.zip delete mode 100644 app-frontend/.yarn/cache/has-unicode-npm-2.0.1-893adb4747-041b4293ad.zip delete mode 100644 app-frontend/.yarn/cache/hpack.js-npm-2.1.6-b08cc088ad-6910e4b9d9.zip delete mode 100644 app-frontend/.yarn/cache/html-minifier-terser-npm-6.0.2-3a759c4206-8362cab367.zip create mode 100644 app-frontend/.yarn/cache/html-minifier-terser-npm-6.1.0-49a405eebd-a244fa944e.zip delete mode 100644 app-frontend/.yarn/cache/http-cache-semantics-npm-4.1.0-860520a31f-c9c29508b2.zip create mode 100644 app-frontend/.yarn/cache/http-cache-semantics-npm-4.1.1-1120131375-362d5ed66b.zip delete mode 100644 app-frontend/.yarn/cache/http-deceiver-npm-1.2.7-4f3aaa5b79-9ae293b0ac.zip delete mode 100644 app-frontend/.yarn/cache/http-errors-npm-1.6.3-9b5bc0b0a8-e48732657e.zip delete mode 100644 app-frontend/.yarn/cache/http-errors-npm-2.0.0-3f1c503428-0e7f76ee8f.zip delete mode 100644 app-frontend/.yarn/cache/http-parser-js-npm-0.5.3-1974f4efad-6a8a609db6.zip delete mode 100644 app-frontend/.yarn/cache/http-proxy-agent-npm-4.0.1-ce9ef61788-2e17f5519f.zip create mode 100644 app-frontend/.yarn/cache/http-proxy-agent-npm-7.0.2-643ed7cc33-d062acfa0c.zip delete mode 100644 app-frontend/.yarn/cache/http-proxy-middleware-npm-2.0.7-886a673e85-4a51bf612b.zip delete mode 100644 app-frontend/.yarn/cache/http-proxy-npm-1.18.1-a313c479c5-2489e98aba.zip delete mode 100644 app-frontend/.yarn/cache/https-proxy-agent-npm-5.0.0-bb777903c3-517037badc.zip create mode 100644 app-frontend/.yarn/cache/https-proxy-agent-npm-7.0.6-27a95c2690-784b628cbd.zip delete mode 100644 app-frontend/.yarn/cache/humanize-ms-npm-1.2.1-e942bd7329-9c7a74a282.zip delete mode 100644 app-frontend/.yarn/cache/iconv-lite-npm-0.4.24-c5c4ac6695-6d3a2dac6e.zip delete mode 100644 app-frontend/.yarn/cache/ignore-npm-5.3.0-fb0f5fa062-51594355ce.zip create mode 100644 app-frontend/.yarn/cache/ignore-npm-5.3.2-346d3ba017-cceb6a4570.zip delete mode 100644 app-frontend/.yarn/cache/image-size-npm-0.5.5-4dec53b956-f41ec6cfcc.zip create mode 100644 app-frontend/.yarn/cache/immer-npm-10.1.1-973ae10d09-9dacf1e8c2.zip create mode 100644 app-frontend/.yarn/cache/immutable-npm-5.0.3-c4195fd7f3-9aca1c7839.zip delete mode 100644 app-frontend/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip delete mode 100644 app-frontend/.yarn/cache/import-local-npm-3.0.3-fd16a368c1-38ae57d35e.zip create mode 100644 app-frontend/.yarn/cache/import-local-npm-3.2.0-bf54ec7842-0b0b0b412b.zip delete mode 100644 app-frontend/.yarn/cache/indent-string-npm-4.0.0-7b717435b2-cd3f5cbc9c.zip delete mode 100644 app-frontend/.yarn/cache/infer-owner-npm-1.0.4-685ac3d2af-181e732764.zip delete mode 100644 app-frontend/.yarn/cache/inflight-npm-1.0.6-ccedb4b908-d2ebd65441.zip delete mode 100644 app-frontend/.yarn/cache/inherits-npm-2.0.3-401e64b080-8771303d66.zip delete mode 100644 app-frontend/.yarn/cache/inherits-npm-2.0.4-c66b3957a0-cd45e923be.zip create mode 100644 app-frontend/.yarn/cache/ip-address-npm-9.0.5-9fa024d42a-1ed81e0672.zip delete mode 100644 app-frontend/.yarn/cache/ip-npm-1.1.9-e72dd3cc0a-29261559b8.zip delete mode 100644 app-frontend/.yarn/cache/ipaddr.js-npm-1.9.1-19ae7878b4-864d0cced0.zip delete mode 100644 app-frontend/.yarn/cache/ipaddr.js-npm-2.1.0-7091ce1549-42c16d95cf.zip delete mode 100644 app-frontend/.yarn/cache/is-arrayish-npm-0.2.1-23927dfb15-73ced84fa3.zip delete mode 100644 app-frontend/.yarn/cache/is-binary-path-npm-2.1.0-e61d46f557-078e51b4f9.zip delete mode 100644 app-frontend/.yarn/cache/is-core-module-npm-2.11.0-70061e141a-9b09ce78f1.zip create mode 100644 app-frontend/.yarn/cache/is-core-module-npm-2.16.1-a54837229e-452b2c2fb7.zip delete mode 100644 app-frontend/.yarn/cache/is-docker-npm-3.0.0-1570e32177-b698118f04.zip delete mode 100644 app-frontend/.yarn/cache/is-fullwidth-code-point-npm-1.0.0-0e436ba1ef-4d46a7465a.zip delete mode 100644 app-frontend/.yarn/cache/is-inside-container-npm-1.0.0-f2c9e9bb96-c50b75a2ab.zip delete mode 100644 app-frontend/.yarn/cache/is-lambda-npm-1.0.1-7ab55bc8a8-93a32f0194.zip delete mode 100644 app-frontend/.yarn/cache/is-network-error-npm-1.0.1-e7ca0446b3-165d61500c.zip delete mode 100644 app-frontend/.yarn/cache/is-plain-obj-npm-3.0.0-a5ae411d5a-a6ebdf8e12.zip delete mode 100644 app-frontend/.yarn/cache/is-what-npm-3.14.1-7260378616-249beb4a8c.zip delete mode 100644 app-frontend/.yarn/cache/is-wsl-npm-3.1.0-311c6d2265-f9734c81f2.zip delete mode 100644 app-frontend/.yarn/cache/isarray-npm-1.0.0-db4f547720-f032df8e02.zip create mode 100644 app-frontend/.yarn/cache/isexe-npm-3.1.1-9c0061eead-7fe1931ee4.zip create mode 100644 app-frontend/.yarn/cache/jackspeak-npm-3.4.3-546bfad080-96f8786eaa.zip create mode 100644 app-frontend/.yarn/cache/jest-util-npm-29.7.0-ff1d59714b-30d58af696.zip create mode 100644 app-frontend/.yarn/cache/jest-worker-npm-29.7.0-4d3567fed6-364cbaef00.zip delete mode 100644 app-frontend/.yarn/cache/jiti-npm-1.21.0-baebd5985a-005a0239e5.zip delete mode 100644 app-frontend/.yarn/cache/js-tokens-npm-4.0.0-0ac852e9e2-af37d0d913.zip delete mode 100644 app-frontend/.yarn/cache/js-yaml-npm-4.1.0-3606f32312-c138a34a3f.zip create mode 100644 app-frontend/.yarn/cache/jsbn-npm-1.1.0-1da0181838-bebe7ae829.zip delete mode 100644 app-frontend/.yarn/cache/launch-editor-npm-2.6.1-0aba6b0e98-e06d193075.zip delete mode 100644 app-frontend/.yarn/cache/less-loader-npm-12.2.0-19b77fcf7d-b952705346.zip delete mode 100644 app-frontend/.yarn/cache/less-npm-4.2.1-300918da9f-931343f468.zip create mode 100644 app-frontend/.yarn/cache/lilconfig-npm-3.1.3-74a77377bb-b932ce1af9.zip delete mode 100644 app-frontend/.yarn/cache/lines-and-columns-npm-1.1.6-23e74fab67-198a5436b1.zip delete mode 100644 app-frontend/.yarn/cache/loader-runner-npm-4.2.0-427f0e7134-89a648e041.zip create mode 100644 app-frontend/.yarn/cache/loader-runner-npm-4.3.0-9ca67df372-555ae00286.zip create mode 100644 app-frontend/.yarn/cache/lodash.memoize-npm-4.1.2-0e6250041f-192b2168f3.zip create mode 100644 app-frontend/.yarn/cache/lodash.uniq-npm-4.5.0-7c270dca85-86246ca64a.zip create mode 100644 app-frontend/.yarn/cache/lru-cache-npm-10.4.3-30c10b861a-e6e9026736.zip delete mode 100644 app-frontend/.yarn/cache/lru-cache-npm-6.0.0-b4c8668fe1-fc1fe2ee20.zip delete mode 100644 app-frontend/.yarn/cache/make-dir-npm-2.1.0-1ddaf205e7-043548886b.zip create mode 100644 app-frontend/.yarn/cache/make-fetch-happen-npm-14.0.3-23b30e8691-fce0385840.zip delete mode 100644 app-frontend/.yarn/cache/make-fetch-happen-npm-9.1.0-23184ad7f6-a868e74fc2.zip create mode 100644 app-frontend/.yarn/cache/mdn-data-npm-2.0.28-9e644d5992-aec475e0c0.zip create mode 100644 app-frontend/.yarn/cache/mdn-data-npm-2.0.30-bf7b39c09a-e4944322bf.zip delete mode 100644 app-frontend/.yarn/cache/media-typer-npm-0.3.0-8674f8f0f5-38e0984db3.zip delete mode 100644 app-frontend/.yarn/cache/memfs-npm-4.7.6-79bbc6057e-b2a4c95635.zip delete mode 100644 app-frontend/.yarn/cache/merge-descriptors-npm-1.0.3-10b44ad75c-52117adbe0.zip delete mode 100644 app-frontend/.yarn/cache/methods-npm-1.1.2-92f6fdb39b-a385dd974f.zip delete mode 100644 app-frontend/.yarn/cache/mime-db-npm-1.50.0-ee51ad7b30-4d553dbf8b.zip delete mode 100644 app-frontend/.yarn/cache/mime-npm-1.6.0-60ae95038a-b7d98bb1e0.zip delete mode 100644 app-frontend/.yarn/cache/mime-types-npm-2.1.33-41bfef7da1-772635f7fe.zip create mode 100644 app-frontend/.yarn/cache/mini-css-extract-plugin-npm-2.9.2-63828e7891-db6ddb8ba5.zip delete mode 100644 app-frontend/.yarn/cache/minimalistic-assert-npm-1.0.1-dc8bb23d29-cc7974a926.zip delete mode 100644 app-frontend/.yarn/cache/minimatch-npm-3.1.2-9405269906-e0b25b04cd.zip create mode 100644 app-frontend/.yarn/cache/minimatch-npm-9.0.5-9aa93d97fa-dd6a8927b0.zip delete mode 100644 app-frontend/.yarn/cache/minipass-collect-npm-1.0.2-3b4676eab5-14df761028.zip create mode 100644 app-frontend/.yarn/cache/minipass-collect-npm-2.0.1-73d3907e40-b251bceea6.zip delete mode 100644 app-frontend/.yarn/cache/minipass-fetch-npm-1.4.1-2d67357feb-4c6f678d2c.zip create mode 100644 app-frontend/.yarn/cache/minipass-fetch-npm-4.0.0-d4e49e0194-4b0772dbee.zip delete mode 100644 app-frontend/.yarn/cache/minipass-npm-3.1.5-63d27aa1b8-e41da4d983.zip create mode 100644 app-frontend/.yarn/cache/minipass-npm-3.3.6-b8d93a945b-a5c6ef069f.zip delete mode 100644 app-frontend/.yarn/cache/minipass-npm-5.0.0-c64fb63c92-61682162d2.zip create mode 100644 app-frontend/.yarn/cache/minipass-npm-7.1.2-3a5327d36d-c25f0ee819.zip delete mode 100644 app-frontend/.yarn/cache/minizlib-npm-2.1.2-ea89cd0cfb-ae0f45436f.zip create mode 100644 app-frontend/.yarn/cache/minizlib-npm-3.0.1-4bdabd978f-622cb85f51.zip delete mode 100644 app-frontend/.yarn/cache/mkdirp-npm-1.0.4-37f6ef56b9-d71b8dcd4b.zip create mode 100644 app-frontend/.yarn/cache/mkdirp-npm-3.0.1-f94bfa769e-16fd79c286.zip delete mode 100644 app-frontend/.yarn/cache/ms-npm-2.0.0-9e1101a471-0e6a22b8b7.zip delete mode 100644 app-frontend/.yarn/cache/ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip delete mode 100644 app-frontend/.yarn/cache/multicast-dns-npm-7.2.5-e1c9c3ec64-e9add8035f.zip delete mode 100644 app-frontend/.yarn/cache/needle-npm-3.2.0-7773d3d8c8-65ec7c7166.zip delete mode 100644 app-frontend/.yarn/cache/negotiator-npm-0.6.2-ba538e167a-eaf267fedd.zip delete mode 100644 app-frontend/.yarn/cache/negotiator-npm-0.6.3-9d50e36171-2723fb822a.zip create mode 100644 app-frontend/.yarn/cache/negotiator-npm-1.0.0-47d727e27e-b5734e8729.zip create mode 100644 app-frontend/.yarn/cache/node-addon-api-npm-7.1.1-bfb302df19-ee1e1ed628.zip delete mode 100644 app-frontend/.yarn/cache/node-forge-npm-1.3.1-f31fd566cc-05bab68686.zip create mode 100644 app-frontend/.yarn/cache/node-gyp-npm-11.0.0-669e34db1b-5d07430e88.zip delete mode 100644 app-frontend/.yarn/cache/node-gyp-npm-8.3.0-11e93b166f-8d1c0d8f80.zip delete mode 100644 app-frontend/.yarn/cache/node-releases-npm-2.0.18-51abc46668-241e5fa955.zip create mode 100644 app-frontend/.yarn/cache/node-releases-npm-2.0.19-b123ed6240-c2b33b4f0c.zip delete mode 100644 app-frontend/.yarn/cache/nopt-npm-5.0.0-304b40fbfe-00f9bb2d16.zip create mode 100644 app-frontend/.yarn/cache/nopt-npm-8.0.0-98d6bf6d52-2d137f64b6.zip delete mode 100644 app-frontend/.yarn/cache/normalize-range-npm-0.1.2-bec5e259e2-9b2f14f093.zip delete mode 100644 app-frontend/.yarn/cache/normalize.css-npm-8.0.1-6124fb39b6-c3af2145c2.zip delete mode 100644 app-frontend/.yarn/cache/npmlog-npm-4.1.2-cfb32957b5-b6b85c9f33.zip delete mode 100644 app-frontend/.yarn/cache/nth-check-npm-2.0.1-69558042d2-5386d035c4.zip create mode 100644 app-frontend/.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip delete mode 100644 app-frontend/.yarn/cache/number-is-nan-npm-1.0.1-845325a0fe-13656bc9aa.zip delete mode 100644 app-frontend/.yarn/cache/object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip delete mode 100644 app-frontend/.yarn/cache/object-inspect-npm-1.13.2-3c6e11a536-7ef65583b6.zip delete mode 100644 app-frontend/.yarn/cache/obuf-npm-1.1.2-8db5fae8dd-53ff4ab3a1.zip delete mode 100644 app-frontend/.yarn/cache/on-finished-npm-2.4.1-907af70f88-8e81472c50.zip delete mode 100644 app-frontend/.yarn/cache/on-headers-npm-1.0.2-e7cd3ea25e-870766c163.zip delete mode 100644 app-frontend/.yarn/cache/once-npm-1.4.0-ccf03ef07a-cd0a885013.zip delete mode 100644 app-frontend/.yarn/cache/open-npm-10.0.3-fafc8b8513-4dc757ad1d.zip delete mode 100644 app-frontend/.yarn/cache/p-map-npm-4.0.0-4677ae07c7-7ba4a2b1e2.zip create mode 100644 app-frontend/.yarn/cache/p-map-npm-7.0.3-93bbec0d8c-2ef48ccfc6.zip delete mode 100644 app-frontend/.yarn/cache/p-retry-npm-6.2.0-00c071e02c-1a5ac16828.zip create mode 100644 app-frontend/.yarn/cache/package-json-from-dist-npm-1.0.1-4631a88465-58ee9538f2.zip delete mode 100644 app-frontend/.yarn/cache/parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip delete mode 100644 app-frontend/.yarn/cache/parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip delete mode 100644 app-frontend/.yarn/cache/parse-node-version-npm-1.0.1-7dd3b14751-ac9b40c647.zip delete mode 100644 app-frontend/.yarn/cache/parseurl-npm-1.3.3-1542397e00-407cee8e0a.zip delete mode 100644 app-frontend/.yarn/cache/path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip create mode 100644 app-frontend/.yarn/cache/path-scurry-npm-1.11.1-aaf8c339af-5e8845c159.zip delete mode 100644 app-frontend/.yarn/cache/path-to-regexp-npm-0.1.12-a9bf1de212-2e30f6a014.zip delete mode 100644 app-frontend/.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip delete mode 100644 app-frontend/.yarn/cache/picocolors-npm-1.0.1-39442f3da8-fa68166d1f.zip delete mode 100644 app-frontend/.yarn/cache/picocolors-npm-1.1.0-ea12a640bd-a2ad60d94d.zip delete mode 100644 app-frontend/.yarn/cache/pify-npm-4.0.1-062756097b-8b97cbf9dc.zip create mode 100644 app-frontend/.yarn/cache/postcss-calc-npm-10.1.0-3964347659-e1e61c618f.zip create mode 100644 app-frontend/.yarn/cache/postcss-colormin-npm-7.0.2-08a84f84c2-cb83d95d21.zip create mode 100644 app-frontend/.yarn/cache/postcss-convert-values-npm-7.0.4-709e2a2326-077481cc98.zip create mode 100644 app-frontend/.yarn/cache/postcss-discard-comments-npm-7.0.3-7bca5e8784-f7c994df0d.zip create mode 100644 app-frontend/.yarn/cache/postcss-discard-duplicates-npm-7.0.1-96084cdabe-0c757bb542.zip create mode 100644 app-frontend/.yarn/cache/postcss-discard-empty-npm-7.0.0-01e04915c0-0c5cea1980.zip create mode 100644 app-frontend/.yarn/cache/postcss-discard-overridden-npm-7.0.0-dc7733ab45-e41c448305.zip delete mode 100644 app-frontend/.yarn/cache/postcss-loader-npm-8.1.1-20cf547c92-7ae38e6351.zip create mode 100644 app-frontend/.yarn/cache/postcss-merge-longhand-npm-7.0.4-4ca1c9a93a-b94b98a9b2.zip create mode 100644 app-frontend/.yarn/cache/postcss-merge-rules-npm-7.0.4-c94fbbce93-f67a4f6e81.zip create mode 100644 app-frontend/.yarn/cache/postcss-minify-font-values-npm-7.0.0-f4e2caa8b1-8578c1d1d4.zip create mode 100644 app-frontend/.yarn/cache/postcss-minify-gradients-npm-7.0.0-f7b51ae77b-9649e255ad.zip create mode 100644 app-frontend/.yarn/cache/postcss-minify-params-npm-7.0.2-1cbb800885-26b6ce4db3.zip create mode 100644 app-frontend/.yarn/cache/postcss-minify-selectors-npm-7.0.4-bbc44478a3-54c74dcb09.zip delete mode 100644 app-frontend/.yarn/cache/postcss-modules-local-by-default-npm-4.0.5-1a623b43f9-b08b01aa7f.zip create mode 100644 app-frontend/.yarn/cache/postcss-modules-local-by-default-npm-4.2.0-3f37e3939f-552329aa39.zip rename app-frontend/.yarn/cache/{postcss-modules-scope-npm-3.2.0-a03c18262e-17c293ad13.zip => postcss-modules-scope-npm-3.2.1-eb0a0538a7-51c747fa15.zip} (67%) create mode 100644 app-frontend/.yarn/cache/postcss-normalize-charset-npm-7.0.0-bdacb840f9-a41043fb81.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-display-values-npm-7.0.0-6a9992d76e-55bbfb4dac.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-positions-npm-7.0.0-75155a14d6-a6b982e567.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-repeat-style-npm-7.0.0-2af427828c-f8ef8cf5ac.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-string-npm-7.0.0-0e5f6f1917-23ea7dd7b2.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-timing-functions-npm-7.0.0-7f393fd35d-f85870b3c8.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-unicode-npm-7.0.2-3d756de91e-cb342f7507.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-url-npm-7.0.0-055009149a-c5edca0646.zip create mode 100644 app-frontend/.yarn/cache/postcss-normalize-whitespace-npm-7.0.0-8bed345e63-c409362e32.zip delete mode 100644 app-frontend/.yarn/cache/postcss-npm-8.4.33-6ba8157009-e22a4594c2.zip create mode 100644 app-frontend/.yarn/cache/postcss-ordered-values-npm-7.0.1-f37f91ed1f-048082c09e.zip create mode 100644 app-frontend/.yarn/cache/postcss-reduce-initial-npm-7.0.2-e37256f84c-5a8260cbf7.zip create mode 100644 app-frontend/.yarn/cache/postcss-reduce-transforms-npm-7.0.0-653cd9844a-1c369a1be8.zip delete mode 100644 app-frontend/.yarn/cache/postcss-selector-parser-npm-6.0.6-4df491c1e3-1afbfdf60b.zip create mode 100644 app-frontend/.yarn/cache/postcss-selector-parser-npm-6.1.2-46a8e03b00-190034c94d.zip create mode 100644 app-frontend/.yarn/cache/postcss-selector-parser-npm-7.0.0-7bb98f14d5-0e92be7281.zip create mode 100644 app-frontend/.yarn/cache/postcss-svgo-npm-7.0.1-22674c6627-4196d9b7ec.zip create mode 100644 app-frontend/.yarn/cache/postcss-unique-selectors-npm-7.0.3-bbadc7397e-c38ca6b5f5.zip delete mode 100644 app-frontend/.yarn/cache/postcss-value-parser-npm-4.1.0-4620e3e849-dac294ad5f.zip create mode 100644 app-frontend/.yarn/cache/proc-log-npm-5.0.0-405173f9b4-35610bdb01.zip delete mode 100644 app-frontend/.yarn/cache/process-nextick-args-npm-2.0.1-b8d7971609-1d38588e52.zip delete mode 100644 app-frontend/.yarn/cache/promise-inflight-npm-1.0.1-5bb925afac-1560d413ea.zip delete mode 100644 app-frontend/.yarn/cache/proxy-addr-npm-2.0.7-dae6552872-f24a0c80af.zip delete mode 100644 app-frontend/.yarn/cache/prr-npm-1.0.1-608d442761-3bca2db047.zip delete mode 100644 app-frontend/.yarn/cache/punycode-npm-2.1.1-26eb3e15cf-939daa010c.zip create mode 100644 app-frontend/.yarn/cache/punycode-npm-2.3.1-97543c420d-febdc4362b.zip delete mode 100644 app-frontend/.yarn/cache/qs-npm-6.13.0-53676ddc84-f548b376e6.zip delete mode 100644 app-frontend/.yarn/cache/range-parser-npm-1.2.1-1a470fa390-ce21ef2a2d.zip delete mode 100644 app-frontend/.yarn/cache/raw-body-npm-2.5.2-5cb9dfebc1-863b5171e1.zip delete mode 100644 app-frontend/.yarn/cache/react-router-dom-npm-7.1.1-e7e2c37675-d7b978959f.zip delete mode 100644 app-frontend/.yarn/cache/react-router-npm-7.1.1-b009809927-f12e229d79.zip delete mode 100644 app-frontend/.yarn/cache/readable-stream-npm-2.3.7-77b22a9818-d04c677c17.zip delete mode 100644 app-frontend/.yarn/cache/readable-stream-npm-3.6.0-23a4a5eb56-b80b3e6a7f.zip delete mode 100644 app-frontend/.yarn/cache/readdirp-npm-3.6.0-f950cc74ab-196b30ef6c.zip create mode 100644 app-frontend/.yarn/cache/readdirp-npm-4.0.2-8001f0febc-4ef9310330.zip delete mode 100644 app-frontend/.yarn/cache/requires-port-npm-1.0.0-fd036b488a-878880ee78.zip delete mode 100644 app-frontend/.yarn/cache/resolve-from-npm-4.0.0-f758ec21bf-91eb76ce83.zip rename app-frontend/.yarn/cache/{resolve-npm-1.22.1-3980488690-4adcfac33f.zip => resolve-npm-1.22.10-d6fd9cdec7-0a398b44da.zip} (62%) rename app-frontend/.yarn/cache/{resolve-patch-61fc5136ce-551dd50076.zip => resolve-patch-b5982cfa8c-d4d878bfe3.zip} (63%) delete mode 100644 app-frontend/.yarn/cache/retry-npm-0.13.1-89eb100ab6-6125ec2e06.zip delete mode 100644 app-frontend/.yarn/cache/rimraf-npm-3.0.2-2cb7dac69a-063ffaccaa.zip create mode 100644 app-frontend/.yarn/cache/rimraf-npm-5.0.10-d0c6647697-f3b8ce81ee.zip delete mode 100644 app-frontend/.yarn/cache/run-applescript-npm-7.0.0-b061c2c4fa-b02462454d.zip delete mode 100644 app-frontend/.yarn/cache/safe-buffer-npm-5.1.2-c27fedf6c4-7eb5b48f2e.zip create mode 100644 app-frontend/.yarn/cache/sass-loader-npm-16.0.4-58fd3a0682-16e3552e04.zip create mode 100644 app-frontend/.yarn/cache/sass-npm-1.83.1-543e7bb3e0-ee4ea5573f.zip delete mode 100644 app-frontend/.yarn/cache/sax-npm-1.2.4-178f05f12f-09b79ff6dc.zip delete mode 100644 app-frontend/.yarn/cache/schema-utils-npm-3.1.1-8704647575-cfcf991f10.zip delete mode 100644 app-frontend/.yarn/cache/schema-utils-npm-4.0.0-4b7d8bb168-b1bbf840a6.zip delete mode 100644 app-frontend/.yarn/cache/schema-utils-npm-4.2.0-e822c5b02e-808784735e.zip create mode 100644 app-frontend/.yarn/cache/schema-utils-npm-4.3.0-6f0a75e2e2-86c5a7c72a.zip delete mode 100644 app-frontend/.yarn/cache/select-hose-npm-2.0.0-8ce63adb52-08cdd629a3.zip delete mode 100644 app-frontend/.yarn/cache/selfsigned-npm-2.4.1-1ca1b883c5-52536623f1.zip delete mode 100644 app-frontend/.yarn/cache/semver-npm-5.7.2-938ee91eaa-fca14418a1.zip delete mode 100644 app-frontend/.yarn/cache/semver-npm-7.3.8-25a996cb4f-c8c04a4d41.zip delete mode 100644 app-frontend/.yarn/cache/semver-npm-7.5.4-c4ad957fcd-985dec0d37.zip create mode 100644 app-frontend/.yarn/cache/semver-npm-7.6.3-57e82c14d5-36b1fbe1a2.zip delete mode 100644 app-frontend/.yarn/cache/send-npm-0.19.0-4297594770-1f6064dea0.zip delete mode 100644 app-frontend/.yarn/cache/serialize-javascript-npm-6.0.1-fac87289ed-f756b1ff34.zip delete mode 100644 app-frontend/.yarn/cache/serve-index-npm-1.9.1-4927052df8-2adce2878d.zip delete mode 100644 app-frontend/.yarn/cache/serve-static-npm-1.16.2-5d8e560aec-7fa9d9c680.zip delete mode 100644 app-frontend/.yarn/cache/set-blocking-npm-2.0.0-49e2cffa24-8980ebf7ae.zip delete mode 100644 app-frontend/.yarn/cache/set-cookie-parser-npm-2.7.1-0e92d9e679-c92b113003.zip delete mode 100644 app-frontend/.yarn/cache/set-function-length-npm-1.2.2-243073748b-505d62b8e0.zip delete mode 100644 app-frontend/.yarn/cache/setprototypeof-npm-1.1.0-7d8becb375-02d2564e02.zip delete mode 100644 app-frontend/.yarn/cache/setprototypeof-npm-1.2.0-0fedbdcd3a-fde1630422.zip delete mode 100644 app-frontend/.yarn/cache/shell-quote-npm-1.8.1-fcccf06093-af19ab5a1e.zip delete mode 100644 app-frontend/.yarn/cache/side-channel-npm-1.0.6-511657386f-eb10944f38.zip delete mode 100644 app-frontend/.yarn/cache/signal-exit-npm-3.0.5-dd7570d7b8-a1d3d0d63f.zip create mode 100644 app-frontend/.yarn/cache/signal-exit-npm-4.1.0-61fb957687-c9fa63bbbd.zip delete mode 100644 app-frontend/.yarn/cache/sockjs-npm-0.3.24-ecb3909016-36312ec977.zip delete mode 100644 app-frontend/.yarn/cache/socks-npm-2.6.1-09133d0d22-6ae166bd1a.zip create mode 100644 app-frontend/.yarn/cache/socks-npm-2.8.3-3532b59899-ffcb622c22.zip delete mode 100644 app-frontend/.yarn/cache/socks-proxy-agent-npm-6.1.0-b9990e465a-7e7116590c.zip create mode 100644 app-frontend/.yarn/cache/socks-proxy-agent-npm-8.0.5-24d77a90dc-ee99e1daca.zip delete mode 100644 app-frontend/.yarn/cache/source-map-js-npm-1.0.2-ee4f9f9b30-38e2d2dd18.zip rename app-frontend/.yarn/cache/{source-map-support-npm-0.5.20-edfc5ce275-7290c7c227.zip => source-map-support-npm-0.5.21-09ca99e250-8317e12d84.zip} (97%) delete mode 100644 app-frontend/.yarn/cache/spdy-npm-4.0.2-7e5782a993-d29b89e48e.zip delete mode 100644 app-frontend/.yarn/cache/spdy-transport-npm-3.0.0-9f4f73f332-b93b606b20.zip create mode 100644 app-frontend/.yarn/cache/sprintf-js-npm-1.1.3-b99efd75b2-e7587128c4.zip create mode 100644 app-frontend/.yarn/cache/ssri-npm-12.0.0-97c0e53d2e-7024c1a6e3.zip delete mode 100644 app-frontend/.yarn/cache/ssri-npm-8.0.1-a369e72ce2-fde247b710.zip delete mode 100644 app-frontend/.yarn/cache/statuses-npm-1.5.0-f88f91b2e9-c469b9519d.zip delete mode 100644 app-frontend/.yarn/cache/statuses-npm-2.0.1-81d2b97fee-18c7623fdb.zip delete mode 100644 app-frontend/.yarn/cache/string-width-npm-1.0.2-01031f9add-5c79439e95.zip create mode 100644 app-frontend/.yarn/cache/string-width-npm-5.1.2-bf60531341-7369deaa29.zip delete mode 100644 app-frontend/.yarn/cache/string_decoder-npm-1.1.1-e46a6c1353-7c41c17ed4.zip delete mode 100644 app-frontend/.yarn/cache/strip-ansi-npm-3.0.1-6aec1365b9-9b974de611.zip create mode 100644 app-frontend/.yarn/cache/strip-ansi-npm-7.1.0-7453b80b79-475f53e9c4.zip create mode 100644 app-frontend/.yarn/cache/stylehacks-npm-7.0.4-167ad0c843-fc9d6b1e0b.zip delete mode 100644 app-frontend/.yarn/cache/supports-color-npm-5.5.0-183ac537bc-5f505c6fa3.zip create mode 100644 app-frontend/.yarn/cache/svgo-npm-3.3.2-69e1d32944-82fdea9b93.zip delete mode 100644 app-frontend/.yarn/cache/tar-npm-6.2.1-237800bb20-bfbfbb2861.zip create mode 100644 app-frontend/.yarn/cache/tar-npm-7.4.3-1dbbd1ffc3-12a2a4fc6d.zip delete mode 100644 app-frontend/.yarn/cache/terser-npm-5.15.1-63dec1247d-9b7cf2b40b.zip delete mode 100644 app-frontend/.yarn/cache/terser-npm-5.27.0-c18b449e2e-9b2c5cb007.zip create mode 100644 app-frontend/.yarn/cache/terser-npm-5.37.0-7dbdc43c6e-3afacf7c38.zip rename app-frontend/.yarn/cache/{terser-webpack-plugin-npm-5.3.10-3bde1920fb-fb1c2436ae.zip => terser-webpack-plugin-npm-5.3.11-1a5bba0883-a8f7c92c75.zip} (90%) delete mode 100644 app-frontend/.yarn/cache/thunky-npm-1.1.0-2d25531f44-825e3bd07a.zip delete mode 100644 app-frontend/.yarn/cache/toidentifier-npm-1.0.1-f759712599-952c29e2a8.zip delete mode 100644 app-frontend/.yarn/cache/tslib-npm-2.3.1-0e21e18015-5e7de59ed9.zip delete mode 100644 app-frontend/.yarn/cache/tslib-npm-2.6.2-4fc8c068d9-bd26c22d36.zip create mode 100644 app-frontend/.yarn/cache/tslib-npm-2.8.1-66590b21b8-3e2e043d5c.zip delete mode 100644 app-frontend/.yarn/cache/turbo-stream-npm-2.4.0-e0cec53097-7079bbc82b.zip delete mode 100644 app-frontend/.yarn/cache/type-is-npm-1.6.18-6dee4d4961-0bd9eeae5e.zip delete mode 100644 app-frontend/.yarn/cache/unique-filename-npm-1.1.1-c885c5095b-9b6969d649.zip create mode 100644 app-frontend/.yarn/cache/unique-filename-npm-4.0.0-bfc100c4e3-6a62094fca.zip delete mode 100644 app-frontend/.yarn/cache/unique-slug-npm-2.0.2-f6ba1ddeb7-6cfaf91976.zip create mode 100644 app-frontend/.yarn/cache/unique-slug-npm-5.0.0-11508c0469-beafdf3d6f.zip delete mode 100644 app-frontend/.yarn/cache/unpipe-npm-1.0.0-2ed2a3c2bf-4fa18d8d8d.zip delete mode 100644 app-frontend/.yarn/cache/update-browserslist-db-npm-1.1.0-3d2cb7d955-d70b9efeaf.zip create mode 100644 app-frontend/.yarn/cache/use-sync-external-store-npm-1.4.0-176448bea1-08bf581a8a.zip delete mode 100644 app-frontend/.yarn/cache/utils-merge-npm-1.0.1-363bbdfbca-5d6949693d.zip delete mode 100644 app-frontend/.yarn/cache/uuid-npm-8.3.2-eca0baba53-9a5f7aa1d6.zip delete mode 100644 app-frontend/.yarn/cache/vary-npm-1.1.2-b49f70ae63-31389debef.zip rename app-frontend/.yarn/cache/{watchpack-npm-2.4.1-23f13203b4-0736ebd20b.zip => watchpack-npm-2.4.2-3e587d5d5b-6bd4c051d9.zip} (78%) delete mode 100644 app-frontend/.yarn/cache/wbuf-npm-1.7.3-cc9e10a084-c18b51c4e1.zip delete mode 100644 app-frontend/.yarn/cache/webpack-dev-middleware-npm-7.4.2-4c13142935-608d101b82.zip delete mode 100644 app-frontend/.yarn/cache/webpack-dev-server-npm-5.2.0-baf75bbb61-f93ca46b03.zip delete mode 100644 app-frontend/.yarn/cache/websocket-driver-npm-0.7.4-a72739da70-17197d265d.zip delete mode 100644 app-frontend/.yarn/cache/websocket-extensions-npm-0.1.4-be839a9e56-b5399b487d.zip create mode 100644 app-frontend/.yarn/cache/which-npm-5.0.0-15aa39eb60-6ec99e89ba.zip delete mode 100644 app-frontend/.yarn/cache/wide-align-npm-1.1.5-889d77e592-d5f8027b9a.zip create mode 100644 app-frontend/.yarn/cache/wrap-ansi-npm-7.0.0-ad6e1a0554-cebdaeca3a.zip create mode 100644 app-frontend/.yarn/cache/wrap-ansi-npm-8.1.0-26a4e6ae28-7b1e4b35e9.zip delete mode 100644 app-frontend/.yarn/cache/wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip delete mode 100644 app-frontend/.yarn/cache/ws-npm-8.18.0-56f68bc4d6-70dfe53f23.zip create mode 100644 app-frontend/.yarn/cache/yallist-npm-5.0.0-8732dd9f1c-1884d272d4.zip create mode 100644 app-frontend/.yarn/cache/zustand-npm-4.5.6-b96df5a380-9efd6faca8.zip create mode 100644 app-frontend/app/src/app.tsx create mode 100644 app-frontend/app/src/components/NavLink.tsx create mode 100644 app-frontend/app/src/components/NavigationComponent.tsx create mode 100644 app-frontend/app/src/components/ThemeSwitch.tsx rename app-frontend/app/src/components/bar/{bar.less => bar.scss} (100%) create mode 100644 app-frontend/app/src/components/bar/useVersionsStore.ts rename app-frontend/app/src/components/category/{category.less => category.scss} (70%) create mode 100644 app-frontend/app/src/components/footer/Footer.tsx rename app-frontend/app/src/components/head/{head.less => head.scss} (100%) delete mode 100644 app-frontend/app/src/components/head/kotlin-14-event.png rename app-frontend/app/src/components/list/{list.less => list.scss} (56%) rename app-frontend/app/src/components/listitem/{listitem.less => listitem.scss} (76%) create mode 100644 app-frontend/app/src/components/login_button/github-logo.svg create mode 100644 app-frontend/app/src/components/login_button/loginButton.tsx create mode 100644 app-frontend/app/src/components/navigation/navbar.tsx create mode 100644 app-frontend/app/src/components/navigation/navbar_default.tsx rename app-frontend/app/src/components/navigation/{Navigation.less => navigation.scss} (84%) rename app-frontend/app/src/components/navigation/{Navigation.tsx => nv.tsx} (82%) delete mode 100644 app-frontend/app/src/components/page_wrapper/page_wrapper.less create mode 100644 app-frontend/app/src/components/page_wrapper/page_wrapper.scss rename app-frontend/app/src/components/search/{search.less => search.scss} (85%) rename app-frontend/app/src/components/version/{KotlinVersion.less => kotlin_version.scss} (100%) rename app-frontend/app/src/components/version/{KotlinVersion.tsx => kotlin_version.tsx} (65%) create mode 100644 app-frontend/app/src/components/war/SupportUkraine.scss create mode 100644 app-frontend/app/src/components/war/SupportUkraine.tsx create mode 100644 app-frontend/app/src/hooks/useFocus.ts create mode 100644 app-frontend/app/src/hooks/useForceUpdateEverySecond.ts create mode 100644 app-frontend/app/src/index.tsx delete mode 100644 app-frontend/app/src/links.ts delete mode 100644 app-frontend/app/src/locations.tsx delete mode 100644 app-frontend/app/src/main.tsx create mode 100644 app-frontend/app/src/pages/404/404.scss create mode 100644 app-frontend/app/src/pages/404/404.tsx create mode 100644 app-frontend/app/src/pages/login/login.tsx delete mode 100644 app-frontend/app/src/root.tsx create mode 100644 app-frontend/app/src/store/themeStore.ts create mode 100644 app-frontend/app/src/store/useLinksStore.ts create mode 100644 app-frontend/app/src/store/useNavigationStore.ts delete mode 100644 app-frontend/app/src/style.less create mode 100644 app-frontend/app/src/style.scss create mode 100644 app-frontend/app/src/useFetch.ts create mode 100644 app-frontend/app/src/utils/queryParams.ts delete mode 100644 app-frontend/app/src/vars.less create mode 100644 app-frontend/app/src/vars.scss delete mode 100644 app-frontend/default.conf delete mode 100644 app-frontend/root/robots.txt delete mode 100644 articles/.new/2016-03912acb0d3a7411a52197d3.awesome.kts delete mode 100644 articles/.new/2016-1efc8ffce3cc834925aa4c38.awesome.kts delete mode 100644 articles/.new/2016-2ffeed9d6973c35ce9706715.awesome.kts delete mode 100644 articles/.new/2016-49c21892145da64d0da7dd46.awesome.kts delete mode 100644 articles/.new/2016-649e83c4a07f241634f53c7e.awesome.kts delete mode 100644 articles/.new/2016-6ac57131c47ae1976f77dd2f.awesome.kts delete mode 100644 articles/.new/2016-8cb358f24247fb7b3dde2c1c.awesome.kts delete mode 100644 articles/.new/2016-8ede24c8c6a721e457b5d938.awesome.kts delete mode 100644 articles/.new/2016-aa65c0e237d34255db9ebbf7.awesome.kts delete mode 100644 articles/.new/2016-ba90e857935f39092d04eca4.awesome.kts delete mode 100644 articles/.new/2016-bb8a72dbab79838a6d8d73b3.awesome.kts delete mode 100644 articles/.new/2016-c4e9708d1c40343edae010d8.awesome.kts delete mode 100644 articles/.new/2016-cca2521e1d43b3500fdcedca.awesome.kts delete mode 100644 articles/2013-310339fbf044daa921b21330.awesome.kts delete mode 100644 articles/2013-3553198685da07c3d7471120.awesome.kts delete mode 100644 articles/2013-606d6240cb4d33d6e450f3ed.awesome.kts delete mode 100644 articles/2013-6df01930de5b789cd543654f.awesome.kts delete mode 100644 articles/2013-9c60e81b64022807e89e7959.awesome.kts delete mode 100644 articles/2014-21b41e58c62d3041fe869125.awesome.kts delete mode 100644 articles/2014-25db6ff51cff9ccd18039078.awesome.kts delete mode 100644 articles/2014-2d0c6e46aab919046ef7eded.awesome.kts delete mode 100644 articles/2014-f6830c7ecbc9f2a1f5f5f26b.awesome.kts delete mode 100644 articles/2015-0deb11e93b9810ab1e0b2d88.awesome.kts delete mode 100644 articles/2015-15e1560ec7019761a6e8a840.awesome.kts delete mode 100644 articles/2015-1dcdb00cb7aeabd57155a7e1.awesome.kts delete mode 100644 articles/2015-278ad978c3f24481040018c2.awesome.kts delete mode 100644 articles/2015-375012f9875f861a8b437791.awesome.kts delete mode 100644 articles/2015-4376c2267cd589d6f0ad3865.awesome.kts delete mode 100644 articles/2015-580c3801999022ec81486732.awesome.kts delete mode 100644 articles/2015-63d0ff8dec6f4b6024e40a03.awesome.kts delete mode 100644 articles/2015-6a426a1822c1adf0e115b223.awesome.kts delete mode 100644 articles/2015-79b0262f809a3a842cc1fc3a.awesome.kts delete mode 100644 articles/2015-7c5d147026965c6474e4953c.awesome.kts delete mode 100644 articles/2015-7f4116d2a6ad6ffb8bbd2d4e.awesome.kts delete mode 100644 articles/2015-98e68615d111e1b1e739e31a.awesome.kts delete mode 100644 articles/2015-a9ae3757b968a8e9a176e802.awesome.kts delete mode 100644 articles/2015-aefed04e1f5bf7b44595ae36.awesome.kts delete mode 100644 articles/2015-cb227cfc53c63a8a9b95fffa.awesome.kts delete mode 100644 articles/2015-e2381c8c7280e63c473af5fe.awesome.kts delete mode 100644 articles/2015-f6140fef22f02a7af341088a.awesome.kts delete mode 100644 articles/2016-0255f596f7c3d38317b38136.awesome.kts delete mode 100644 articles/2016-027aae71a81a93d02678e90f.awesome.kts delete mode 100644 articles/2016-02ba3f66f0b171f296f83fbe.awesome.kts delete mode 100644 articles/2016-02e8a7d319a3f808ba2fdf55.awesome.kts delete mode 100644 articles/2016-034667ecfbc594d76a3d1c6e.awesome.kts delete mode 100644 articles/2016-069a24229854109b1de94ada.awesome.kts delete mode 100644 articles/2016-06e38c50d6f21f2e6f9fa26f.awesome.kts delete mode 100644 articles/2016-07fad586977736c6dd7ee1e6.awesome.kts delete mode 100644 articles/2016-08597c8863d0a4eca032abd3.awesome.kts delete mode 100644 articles/2016-08965fd81d86020ef1515f43.awesome.kts delete mode 100644 articles/2016-08db274630a60c20d57e7f5a.awesome.kts delete mode 100644 articles/2016-094b5bd4ba588cdf7e82fabb.awesome.kts delete mode 100644 articles/2016-0a9ea2fe281aaf2111e1b7d1.awesome.kts delete mode 100644 articles/2016-0c7e82fb01baa5f523161cb1.awesome.kts delete mode 100644 articles/2016-0d0928e9334d0f7a8b412ae3.awesome.kts delete mode 100644 articles/2016-0dc0a3e165b2c55edce38984.awesome.kts delete mode 100644 articles/2016-0ea59e1e0f84b58e26618f0e.awesome.kts delete mode 100644 articles/2016-0ff8d19eae299b390276c06e.awesome.kts delete mode 100644 articles/2016-1082409b8060514f49289d33.awesome.kts delete mode 100644 articles/2016-150bc21134f535f106e66b08.awesome.kts delete mode 100644 articles/2016-171710c9aabb3929614e6560.awesome.kts delete mode 100644 articles/2016-17751f671ea70fd172df2f60.awesome.kts delete mode 100644 articles/2016-186cd90a4b50bbfe55337300.awesome.kts delete mode 100644 articles/2016-1921e416508250a97680a2e5.awesome.kts delete mode 100644 articles/2016-19e54dbc2fd88fda57144a1c.awesome.kts delete mode 100644 articles/2016-1c21a9860a24e199dfa83885.awesome.kts delete mode 100644 articles/2016-1cd4f8fd896493ae0633f628.awesome.kts delete mode 100644 articles/2016-1dd9794e1f7a731b48b14dfc.awesome.kts delete mode 100644 articles/2016-1df2465808fa7483de3c5973.awesome.kts delete mode 100644 articles/2016-1eca8cede064245b31387182.awesome.kts delete mode 100644 articles/2016-2086fdbbfac5ea60cfd1a494.awesome.kts delete mode 100644 articles/2016-23b7705664d2fb58165399cb.awesome.kts delete mode 100644 articles/2016-24de196448ba573dc4f9dbfa.awesome.kts delete mode 100644 articles/2016-263cdeaae09d1eb2d85cd450.awesome.kts delete mode 100644 articles/2016-26446d09448076aec6a5728c.awesome.kts delete mode 100644 articles/2016-28cc676b5006aaebd64a918c.awesome.kts delete mode 100644 articles/2016-2bb27a6a36647d2a1cd465a7.awesome.kts delete mode 100644 articles/2016-2be0dd6beaba65c40ea65752.awesome.kts delete mode 100644 articles/2016-2c06849d49f447b3ad2e1478.awesome.kts delete mode 100644 articles/2016-2ca92efca584f8a08e689787.awesome.kts delete mode 100644 articles/2016-2caca33c9d8ace18743e51e4.awesome.kts delete mode 100644 articles/2016-2cd3ded1b96e98db2b21e927.awesome.kts delete mode 100644 articles/2016-2e1dbd77c93367ee579e5148.awesome.kts delete mode 100644 articles/2016-2f376f45a35f3a6f1e338a92.awesome.kts delete mode 100644 articles/2016-30199f6c963e3320522cc1cf.awesome.kts delete mode 100644 articles/2016-31187810bf5acedd398fbf79.awesome.kts delete mode 100644 articles/2016-336105aa8e547a9ff1e3b57e.awesome.kts delete mode 100644 articles/2016-3471005a80876027458b8f92.awesome.kts delete mode 100644 articles/2016-35c625dee068c0b1f794180c.awesome.kts delete mode 100644 articles/2016-36ec23459c6bf8b8bc759f3f.awesome.kts delete mode 100644 articles/2016-38bc6954835b269270362118.awesome.kts delete mode 100644 articles/2016-394ae1494abaea321bcd5f9a.awesome.kts delete mode 100644 articles/2016-39e4ad67f25e4a709fcf8c87.awesome.kts delete mode 100644 articles/2016-3a2ff9ad40f3b56e00edd557.awesome.kts delete mode 100644 articles/2016-3a5aa1d842e7c6751456cf8d.awesome.kts delete mode 100644 articles/2016-3a5fcf143e5e848bc7b7996e.awesome.kts delete mode 100644 articles/2016-3ab6d61fc70f57a2d40513aa.awesome.kts delete mode 100644 articles/2016-3b9081ba7ea6c0396e5f81b1.awesome.kts delete mode 100644 articles/2016-3c5ebd759148c39f151c080a.awesome.kts delete mode 100644 articles/2016-3c877390446cd36d22c5879d.awesome.kts delete mode 100644 articles/2016-3d3215ed5fbef44ba72736f4.awesome.kts delete mode 100644 articles/2016-4255d0011abd9a1d037e3bac.awesome.kts delete mode 100644 articles/2016-42c0c5dc0da3dd622d346b04.awesome.kts delete mode 100644 articles/2016-42d48c9778b93c914a0c748e.awesome.kts delete mode 100644 articles/2016-42dbe436846341e58165e969.awesome.kts delete mode 100644 articles/2016-431cd2b53e4b87af63c6536a.awesome.kts delete mode 100644 articles/2016-43287111c29e26b28014534d.awesome.kts delete mode 100644 articles/2016-445010237e59c20cda51753f.awesome.kts delete mode 100644 articles/2016-46bc8b61bfa938b11d5aeff3.awesome.kts delete mode 100644 articles/2016-4a78dcc3104bc63fd564f0c7.awesome.kts delete mode 100644 articles/2016-4a9ac0dcb3b751519f981223.awesome.kts delete mode 100644 articles/2016-4bb4c8661f3d63ca3f96cf26.awesome.kts delete mode 100644 articles/2016-4be93fb1b02fec72a1479d6a.awesome.kts delete mode 100644 articles/2016-4bf9a8ee2bf6cf60317c14b7.awesome.kts delete mode 100644 articles/2016-4e28fdf6ba991d35423aee70.awesome.kts delete mode 100644 articles/2016-5115913c9d7f459ff66f9db3.awesome.kts delete mode 100644 articles/2016-521bde91b0fbf61797491770.awesome.kts delete mode 100644 articles/2016-526eefda5c77b656004c50a5.awesome.kts delete mode 100644 articles/2016-52e4f25163c33faf05aeebcb.awesome.kts delete mode 100644 articles/2016-535e4b63224ab68305384943.awesome.kts delete mode 100644 articles/2016-550b8c318b6276a5cb786448.awesome.kts delete mode 100644 articles/2016-5698768849f64ad5815c7e4b.awesome.kts delete mode 100644 articles/2016-5763a68e9736b0496e5c8113.awesome.kts delete mode 100644 articles/2016-57db3517f35bbd8048005e74.awesome.kts delete mode 100644 articles/2016-5a74f6cafe19ecbc9f86b89d.awesome.kts delete mode 100644 articles/2016-5c31f93b944c089bf1641e11.awesome.kts delete mode 100644 articles/2016-5d4af8c65e1a823fefc45e19.awesome.kts delete mode 100644 articles/2016-5df0379e0350226db4123c19.awesome.kts delete mode 100644 articles/2016-5e88df04de910b5dd829c468.awesome.kts delete mode 100644 articles/2016-5ec1b6f5bf821f50de0bd335.awesome.kts delete mode 100644 articles/2016-5fc3f6c9609be18717946798.awesome.kts delete mode 100644 articles/2016-602c78d41f320f3595a8259b.awesome.kts delete mode 100644 articles/2016-6131a140d09a3a8ec83ad1ff.awesome.kts delete mode 100644 articles/2016-627aacdb3d340bbf878a4278.awesome.kts delete mode 100644 articles/2016-64e869d3abea5e4867bfe2df.awesome.kts delete mode 100644 articles/2016-650dd4cc4b0da798638f69f6.awesome.kts delete mode 100644 articles/2016-65f7d13a8eb71cc821ce3455.awesome.kts delete mode 100644 articles/2016-68ceb945bb0381441a588ced.awesome.kts delete mode 100644 articles/2016-68f27b2fbbb4ca118b011699.awesome.kts delete mode 100644 articles/2016-68f58e9d99eab57c5347d7ed.awesome.kts delete mode 100644 articles/2016-693970ae59d1fe2650044308.awesome.kts delete mode 100644 articles/2016-693ac2cb019180827c2e3e2c.awesome.kts delete mode 100644 articles/2016-69a156e2bbb885ec402a1dcb.awesome.kts delete mode 100644 articles/2016-6ac2bf442514bb4883d4d99c.awesome.kts delete mode 100644 articles/2016-6bceef2cd285810a50be8e75.awesome.kts delete mode 100644 articles/2016-6c7171a62ab893ea5d2e8e92.awesome.kts delete mode 100644 articles/2016-6ca6077a7ae2335e81fdfa5b.awesome.kts delete mode 100644 articles/2016-6caed4bbf5f5d5314cf61981.awesome.kts delete mode 100644 articles/2016-6efac316422ce36e824ece9e.awesome.kts delete mode 100644 articles/2016-709a075cf11ecb6d66360279.awesome.kts delete mode 100644 articles/2016-71753534bd01f6b3825d40e8.awesome.kts delete mode 100644 articles/2016-73decb131be4e2fd04536d0e.awesome.kts delete mode 100644 articles/2016-75b036f1e4f57bc926e246e3.awesome.kts delete mode 100644 articles/2016-75f6af728f701003e4aa71db.awesome.kts delete mode 100644 articles/2016-7687a8224129a8d0b1d71107.awesome.kts delete mode 100644 articles/2016-77d3cbd423477d558763ac8d.awesome.kts delete mode 100644 articles/2016-799f92203cb8cdd6ce2c41a2.awesome.kts delete mode 100644 articles/2016-7c2a676ce11cc26b5bedd5b3.awesome.kts delete mode 100644 articles/2016-7d056606015a7df3ce5df2dc.awesome.kts delete mode 100644 articles/2016-7dd5994ebc729a04f3343fc3.awesome.kts delete mode 100644 articles/2016-7f349c80a1451da5f02992be.awesome.kts delete mode 100644 articles/2016-7f3ec77668d385906bed0947.awesome.kts delete mode 100644 articles/2016-7f79a7582fb19ca8467ca38c.awesome.kts delete mode 100644 articles/2016-7fc0816b244c3dce076f60b8.awesome.kts delete mode 100644 articles/2016-810797be34edb6b4dbd523dd.awesome.kts delete mode 100644 articles/2016-8261cd1f143a31a1d6f98255.awesome.kts delete mode 100644 articles/2016-833cee9b17227db925b4f3cc.awesome.kts delete mode 100644 articles/2016-835a73611dcac42a9fdf07a2.awesome.kts delete mode 100644 articles/2016-843be12f18c6c9882fe77d0e.awesome.kts delete mode 100644 articles/2016-844670a7df369c6438fb380a.awesome.kts delete mode 100644 articles/2016-84fe8eb2230f7a340e89ee70.awesome.kts delete mode 100644 articles/2016-85180ff477f05011282f9be3.awesome.kts delete mode 100644 articles/2016-85f92ecc92688392132a157c.awesome.kts delete mode 100644 articles/2016-863ac14f478bdfbce79e919b.awesome.kts delete mode 100644 articles/2016-876cca938ee0af6f010f1593.awesome.kts delete mode 100644 articles/2016-88b56901143b40a8a9cc20c3.awesome.kts delete mode 100644 articles/2016-895451b37b386516d9f2da01.awesome.kts delete mode 100644 articles/2016-89644d98c7d2007da5af6d89.awesome.kts delete mode 100644 articles/2016-8b31b17925b3f3447ba91137.awesome.kts delete mode 100644 articles/2016-8bba940f8bbf96c5979c4e30.awesome.kts delete mode 100644 articles/2016-8c0aade7a6e73ac737cfcc3e.awesome.kts delete mode 100644 articles/2016-8f42bb4eebaaff08579becd7.awesome.kts delete mode 100644 articles/2016-8f8b62f4e486d7127172f768.awesome.kts delete mode 100644 articles/2016-8fb12953b1b146c2aa3c12a9.awesome.kts delete mode 100644 articles/2016-921877edeadfeddfb29ba857.awesome.kts delete mode 100644 articles/2016-93c95fb8ca4bb0937590e3cb.awesome.kts delete mode 100644 articles/2016-93f0eef7ff14099256b10c34.awesome.kts delete mode 100644 articles/2016-942a2e24c740bbd824880e2f.awesome.kts delete mode 100644 articles/2016-948f7365af30de3f7245e6db.awesome.kts delete mode 100644 articles/2016-95cfbac30b2c64a62e6774e9.awesome.kts delete mode 100644 articles/2016-96aa9f29f55ec2d8c92b3b94.awesome.kts delete mode 100644 articles/2016-96c57789390db765cddc1be9.awesome.kts delete mode 100644 articles/2016-96f2e54594c534c2555819c6.awesome.kts delete mode 100644 articles/2016-977fbdc6e922ff62e9e9400a.awesome.kts delete mode 100644 articles/2016-98937645073d24a2f48bfc41.awesome.kts delete mode 100644 articles/2016-9b1a52c2b0880e3842a267b1.awesome.kts delete mode 100644 articles/2016-9c5c384f05d7f31a6e358b1b.awesome.kts delete mode 100644 articles/2016-9db18b46178528ce1a403ea9.awesome.kts delete mode 100644 articles/2016-9f30dd7283f90d50dc9a3d1e.awesome.kts delete mode 100644 articles/2016-a0c3367fff4406be12a7a110.awesome.kts delete mode 100644 articles/2016-a171e4515c73ed8413c9849b.awesome.kts delete mode 100644 articles/2016-a1ba51190e8b6e9eb7fe97d2.awesome.kts delete mode 100644 articles/2016-a20729d546b03752baa768bc.awesome.kts delete mode 100644 articles/2016-a210e5967b6f195bb5b8b436.awesome.kts delete mode 100644 articles/2016-a2a546cc6730a821f5dc4236.awesome.kts delete mode 100644 articles/2016-a33d5f69f7e730c614535d0d.awesome.kts delete mode 100644 articles/2016-a3c2d7d8dfdc076ce7fc084a.awesome.kts delete mode 100644 articles/2016-a489989c4509a072783d5415.awesome.kts delete mode 100644 articles/2016-a4ef66835a28eb0cd4216f9e.awesome.kts delete mode 100644 articles/2016-a58012e1cd6d4728f93f942c.awesome.kts delete mode 100644 articles/2016-a9056ccf26b3b2285837afe6.awesome.kts delete mode 100644 articles/2016-a97664dd23b685690e8c99f5.awesome.kts delete mode 100644 articles/2016-aa228bbd646683765bba8a05.awesome.kts delete mode 100644 articles/2016-aa44a938de92a1476940ff4a.awesome.kts delete mode 100644 articles/2016-ace00c882586674e12b170ba.awesome.kts delete mode 100644 articles/2016-af945df7eb11118cd174d958.awesome.kts delete mode 100644 articles/2016-b014b49018b0dc6a8f9fc1fb.awesome.kts delete mode 100644 articles/2016-b04fa09578d1585c9bf6a8b5.awesome.kts delete mode 100644 articles/2016-b05d9deb1d58134bf0de1cfe.awesome.kts delete mode 100644 articles/2016-b119f5a861ef4335d5e13eb1.awesome.kts delete mode 100644 articles/2016-b13ba4d768f9af6e28c7b635.awesome.kts delete mode 100644 articles/2016-b405f88ac956f7d86513b77a.awesome.kts delete mode 100644 articles/2016-b6033ea3b43f2f5719fa4074.awesome.kts delete mode 100644 articles/2016-b6689772aa5900d935b245b8.awesome.kts delete mode 100644 articles/2016-b737f02ad34d6d02f9065ff1.awesome.kts delete mode 100644 articles/2016-b7d94770fa283965d36edb4e.awesome.kts delete mode 100644 articles/2016-b971195fda09015a993e97ac.awesome.kts delete mode 100644 articles/2016-b97fc8f25d9e0b63e40a8eed.awesome.kts delete mode 100644 articles/2016-ba727eeeabedc8ef3055f836.awesome.kts delete mode 100644 articles/2016-bb84aba446e7533a023e7787.awesome.kts delete mode 100644 articles/2016-bcf2a5cfb216a3bd6c94b179.awesome.kts delete mode 100644 articles/2016-bf89a524fe044a02fbec70e3.awesome.kts delete mode 100644 articles/2016-c0f49c8bcd5a444cbffc630c.awesome.kts delete mode 100644 articles/2016-c135ec1b836b866eb8ef5ffd.awesome.kts delete mode 100644 articles/2016-c210d58e4ab39ac951453ecf.awesome.kts delete mode 100644 articles/2016-c49ea29a4cf7dd51f954b1b5.awesome.kts delete mode 100644 articles/2016-c52161aa4c5732511e2eceab.awesome.kts delete mode 100644 articles/2016-cad6310e3645a04e011a4a98.awesome.kts delete mode 100644 articles/2016-cc4f6de957d37f66b0bbfd99.awesome.kts delete mode 100644 articles/2016-ce30221c54569430212817f9.awesome.kts delete mode 100644 articles/2016-cf3c017775469362dff43711.awesome.kts delete mode 100644 articles/2016-cfadd5dd77d4539669f6fd63.awesome.kts delete mode 100644 articles/2016-cfbf0585c22d63e27d96cd1c.awesome.kts delete mode 100644 articles/2016-d1e76e4f9af8b3e921c2173d.awesome.kts delete mode 100644 articles/2016-d27fb35714a50d4f8e8bd4ec.awesome.kts delete mode 100644 articles/2016-d72e078fcaf908c01f8cfd5d.awesome.kts delete mode 100644 articles/2016-d77af2564744b28f6dc3438b.awesome.kts delete mode 100644 articles/2016-d8438acc1948008d644e8b31.awesome.kts delete mode 100644 articles/2016-d8c8031bf2f944833a3d1bd3.awesome.kts delete mode 100644 articles/2016-d985e297a518cf1f818682ed.awesome.kts delete mode 100644 articles/2016-dc0f7d9d0f146696fada182f.awesome.kts delete mode 100644 articles/2016-dcc6a34e3894b6061b7c265e.awesome.kts delete mode 100644 articles/2016-dcdeeb41ff3e4dcf21bd9d53.awesome.kts delete mode 100644 articles/2016-dd0954e9a90b6c7d52e48f70.awesome.kts delete mode 100644 articles/2016-ddcbd4c945e89c72618c5e7c.awesome.kts delete mode 100644 articles/2016-de238a388570dd0ecdb72266.awesome.kts delete mode 100644 articles/2016-deca01d6cd8229c7934d5efc.awesome.kts delete mode 100644 articles/2016-e12dc1675e54642217216764.awesome.kts delete mode 100644 articles/2016-e12ef899063e57c86f2127ed.awesome.kts delete mode 100644 articles/2016-e15acecb122529580b029541.awesome.kts delete mode 100644 articles/2016-e1915d975fb3922b38bbdc7c.awesome.kts delete mode 100644 articles/2016-e1ec3da29327450d9db288e1.awesome.kts delete mode 100644 articles/2016-e4b28497862014c8fc54b28a.awesome.kts delete mode 100644 articles/2016-e51ccecd8b58ea38d9a4d587.awesome.kts delete mode 100644 articles/2016-e64c00166e68889e640210c7.awesome.kts delete mode 100644 articles/2016-e67d39fec1b4e33636615edb.awesome.kts delete mode 100644 articles/2016-e70073bcff0ea2bf1616eb71.awesome.kts delete mode 100644 articles/2016-eb4ad759de0aeb7152acd4de.awesome.kts delete mode 100644 articles/2016-ec4ada3f896d6582c993ec72.awesome.kts delete mode 100644 articles/2016-edfab15e3a91965c5f200d34.awesome.kts delete mode 100644 articles/2016-f08cee1f3e73a2c99afe98cb.awesome.kts delete mode 100644 articles/2016-f0c2aaa9cf1991ea2ce10fff.awesome.kts delete mode 100644 articles/2016-f3a0a6bc82694103ae2fb93a.awesome.kts delete mode 100644 articles/2016-f6716af4bb8b1242e1bb13fc.awesome.kts delete mode 100644 articles/2016-f7b489a06940f46a1a3ca938.awesome.kts delete mode 100644 articles/2016-f901c99406a0d7d75401f639.awesome.kts delete mode 100644 articles/2016-fb23003416802ad89073be4b.awesome.kts delete mode 100644 articles/2016-fd42b2f2f7ed8318533011bb.awesome.kts delete mode 100644 articles/2016-fdd73548da8519c947637a45.awesome.kts delete mode 100644 articles/2016-ff626f84ee081bb09fabd20a.awesome.kts delete mode 100644 articles/2016-ff8f29fdae0a2726f72be996.awesome.kts delete mode 100644 articles/2017-02e680cba3e75ff13ec593b4.awesome.kts delete mode 100644 articles/2017-0669d1750e756995be758d82.awesome.kts delete mode 100644 articles/2017-06f1a06fc5158e2abab26aa6.awesome.kts delete mode 100644 articles/2017-14f430dfbde488d5f9ac5d6d.awesome.kts delete mode 100644 articles/2017-18a29f8d330211ffd29ac36c.awesome.kts delete mode 100644 articles/2017-2de67c200ee1243e75c329d6.awesome.kts delete mode 100644 articles/2017-3541606739ef99cc9edb185f.awesome.kts delete mode 100644 articles/2017-36d30408aafc38ff1dfb0c4e.awesome.kts delete mode 100644 articles/2017-39ab27c5cda7750996cf385b.awesome.kts delete mode 100644 articles/2017-3c0f1cb6210fcaf6961c9540.awesome.kts delete mode 100644 articles/2017-3c9c0e34f73569ac0fb2a07c.awesome.kts delete mode 100644 articles/2017-4b1bf8ddff136175396ca0af.awesome.kts delete mode 100644 articles/2017-50e184a426915a5aae38e2f5.awesome.kts delete mode 100644 articles/2017-55bf98f5ebb96a3fc0fbc947.awesome.kts delete mode 100644 articles/2017-79f41dfc1fdb148e0f82706d.awesome.kts delete mode 100644 articles/2017-7baeda53dff17ac99bf6aa42.awesome.kts delete mode 100644 articles/2017-7bc151aee76654415d4fd1ab.awesome.kts delete mode 100644 articles/2017-7dbfec506fbf710ddeba3472.awesome.kts delete mode 100644 articles/2017-7dde9a7a53fff296313c82d3.awesome.kts delete mode 100644 articles/2017-8695bcc02c025a816551d473.awesome.kts delete mode 100644 articles/2017-8bbafa401c91ca8e167c0ace.awesome.kts delete mode 100644 articles/2017-916b3924483991f3fac093b0.awesome.kts delete mode 100644 articles/2017-9faf0eb63cc2cf86f9ca63b9.awesome.kts delete mode 100644 articles/2017-a232bc9e6c7e3ce4cfe83f0a.awesome.kts delete mode 100644 articles/2017-a2d8ca8f90a29ec65026578a.awesome.kts delete mode 100644 articles/2017-ab514289ea34d74fe01126a3.awesome.kts delete mode 100644 articles/2017-af0e236ef5ef906ac97df42d.awesome.kts delete mode 100644 articles/2017-bf845594530a25b4df848ccb.awesome.kts delete mode 100644 articles/2017-c063076c586c25b77a7c5b21.awesome.kts delete mode 100644 articles/2017-cd6421f7c3f0c6c08cc2107d.awesome.kts delete mode 100644 articles/2017-cdf5798e392c1d05c6dd08f2.awesome.kts delete mode 100644 articles/2017-d5127ac07a4c323b952dadcd.awesome.kts delete mode 100644 articles/2017-d54741b69c8e4ca7cb6d42a4.awesome.kts delete mode 100644 articles/2017-da12f95f1a2cb71cfa573022.awesome.kts delete mode 100644 articles/2017-dcb512e6b77bb34b75da58c7.awesome.kts delete mode 100644 articles/2017-e740bf420b3627bdf5ea3c10.awesome.kts delete mode 100644 articles/2017-f1453f1437c28abbd68d16af.awesome.kts delete mode 100644 articles/2017-f2681159467e3cb3ebedab94.awesome.kts delete mode 100644 articles/2017-f9874d2b61dd799265dede6b.awesome.kts delete mode 100644 articles/2018-11bc85488320be64f72e6fec.awesome.kts delete mode 100644 readme/LICENSE delete mode 100644 src/main/kotlin/link/kotlin/scripts/Application.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/ApplicationModule.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/ArticlesSource.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/AwesomeKotlinGenerator.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/CategoryProcessor.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/KotlinVersionFetcher.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/LinksChecker.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/LinksSource.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/MarkdownRenderer.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/SiteGenerator.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/SitemapGenerator.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/dsl/DSL.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/import/Communities.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/import/Readability.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/import/user-group-list.md delete mode 100644 src/main/kotlin/link/kotlin/scripts/model/ApplicationConfiguration.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/model/Dto.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/model/Link.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/scripting/AwesomeScript.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/scripting/ScriptEvaluator.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/utils/Cache.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/utils/CopyTask.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/utils/Fs.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/utils/HttpClient.kt delete mode 100644 src/main/kotlin/link/kotlin/scripts/utils/Utils.kt delete mode 100644 src/main/resources/META-INF/kotlin/script/templates/link.kotlin.scripts.scripting.AwesomeScript.classname delete mode 100644 src/main/resources/links/Android.awesome.kts delete mode 100644 src/main/resources/links/Archive.awesome.kts delete mode 100644 src/main/resources/links/JavaScript.awesome.kts delete mode 100644 src/main/resources/links/Libraries.awesome.kts delete mode 100644 src/main/resources/links/Links.awesome.kts delete mode 100644 src/main/resources/links/Native.awesome.kts delete mode 100644 src/main/resources/links/Projects.awesome.kts delete mode 100644 src/main/resources/links/UserGroups.awesome.kts delete mode 100644 src/main/resources/links/WebAssembly.awesome.kts delete mode 100644 src/main/resources/logback.xml delete mode 100644 src/test/kotlin/link/kotlin/scripts/ReadmeGeneratorTest.kt delete mode 100644 src/test/kotlin/link/kotlin/scripts/VersionFetcherManualTest.kt delete mode 100644 src/test/kotlin/link/kotlin/scripts/utils/ParseInstantTest.kt diff --git a/.editorconfig b/.editorconfig index 4ce1ab2b9..0c346a1d0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,5 @@ indent_size=2 [build.gradle.kts] indent_size=4 -[*.{js,ts,tsx,less,html,yml,json}] +[*.{js,ts,tsx,scss,html,yml,json}] indent_size=2 diff --git a/.env.example b/.env.example index 78f129504..1a40c5984 100644 --- a/.env.example +++ b/.env.example @@ -1,11 +1,26 @@ -AWESOME_JWT_SECRET= +AWESOME__JWT__ISSUER=https://kotlin.link/ +AWESOME__JWT__AUDIENCE=https://kotlin.link/ +AWESOME__JWT__REALM=awesome-kotlin/v2 +AWESOME__JWT__SECRET= -AWESOME_GITHUB_CLIENT_ID= -AWESOME_GITHUB_CLIENT_SECRET= -AWESOME_GITHUB_REDIRECT_URL=http://localhost:9566/auth/github +AWESOME__GITHUB__CLIENT_ID= +AWESOME__GITHUB__CLIENT_SECRET= +AWESOME__GITHUB__REDIRECT_URL=http://localhost:9566/auth/github -AWESOME_JDBC_PORT=9567 -AWESOME_JDBC_HOST=localhost +AWESOME__JDBC__PORT=9567 +AWESOME__JDBC__HOST=localhost -AWESOME_SERVER_PORT=9566 -AWESOME_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT=0s +AWESOME__SERVER__PORT=9566 +AWESOME__SERVER__HOST=localhost +AWESOME__SERVER__GRACEFUL_SHUTDOWN_TIMEOUT=10s +AWESOME__SERVER__REACT_DIST_PATH=app-frontend/dist/ + +AWESOME__WEB__INTERNAL__HOST=localhost +AWESOME__WEB__INTERNAL__PORT=9566 +AWESOME__WEB__INTERNAL__PROTOCOL=http + +AWESOME__WEB__EXTERNAL__HOST=kotlin.link +AWESOME__WEB__EXTERNAL__PORT=443 +AWESOME__WEB__EXTERNAL__PROTOCOL=https + +GH_TOKEN= diff --git a/.github/contributing.md b/.github/contributing.md index 66c9607ef..7aa1fb54f 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -2,16 +2,6 @@ ## Adding to this list -This awesome list contains two views: standard github README page view, and nice website with search. - -**To contribute** to both places you need: - -1. Checkout `main` branch; -2. Edit **[src/main/resources/links/](https://github.com/Heapy/awesome-kotlin/tree/main/src/main/resources/links)${category}.awesome.kts**; -3. Create PR. - -*Happy contributing!* - -## How to update website/readme? - -Build on Travis CI automatically updates website and readme on pushes to **main** branch. +Login to https://kotlin.link/ and click on the "Add a link" button. +Fill in the form and submit it. +The link will be added to the list after it has been reviewed. diff --git a/.github/issue_template.md b/.github/issue_template.md index 9ad51eac2..49fa8e8b0 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,2 +1,2 @@ Please use issues only for submitting bugs, feature requests, etc. -Use Pull Requests to submitting projects or links. +Use https://kotlin.link/ for submitting projects or links. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e7655ec72..8b1378917 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1 @@ -Make sure that you are making pull request against [`main`](https://github.com/Heapy/awesome-kotlin/tree/main) branch. Pull requests against `readme` branch will not be accepted, because all manual changes to this branch will be overridden by changes from `main` branch. Consult [contributing.md](https://github.com/Heapy/awesome-kotlin/blob/main/.github/contributing.md) for details. -Checklist: - -- [ ] Is this pull request against the branch `main`? diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2b1d0e9f..52da1c383 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,9 @@ name: "Build" + on: push: pull_request: + jobs: check: if: ${{ github.event_name == 'pull_request' }} diff --git a/.gitignore b/.gitignore index 63e000280..5eb68df24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -# Generated -/readme/README.md - # Local Configuration .env diff --git a/.run/Awesome Kotlin 1.0.run.xml b/.run/Awesome Kotlin 1.0.run.xml deleted file mode 100644 index 111463e4f..000000000 --- a/.run/Awesome Kotlin 1.0.run.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/Backlog.txt b/Backlog.txt index 6c392de1a..10d58a936 100644 --- a/Backlog.txt +++ b/Backlog.txt @@ -4,6 +4,15 @@ Followers Tags -> Topics Topic: Graph https://awesomejava.resamvi.io/ +https://akkurate.dev/ +https://github.com/UselessMnemonic/Pak +https://github.com/daniel-rusu/pods4k/tree/main +https://github.com/Saumya-Bhatt/karya +https://github.com/nbadal/ktlint-intellij-plugin +https://github.com/mockoon/mockoon +https://github.com/kevincianfarini/alchemist +https://strikt.io/ +https://github.com/fluxo-kt/fluxo Possible categories: Serialization diff --git a/README.md b/README.md index db7c58953..37559455b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A curated list of awesome Kotlin related stuff inspired by awesome-java. :octocat: -Discuss this project in [Kotlin Slack](http://slack.kotlinlang.org/), channel: **# awesome-kotlin** +Discuss this project in [Kotlin Slack](http://slack.kotlinlang.org/), channel: **#awesome-kotlin** [![List of Awesome List Badge](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) [![Build](https://github.com/Heapy/awesome-kotlin/actions/workflows/build.yml/badge.svg)](https://github.com/Heapy/awesome-kotlin/actions/workflows/build.yml) [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/Heapy/awesome-kotlin) @@ -10,8 +10,6 @@ Discuss this project in [Kotlin Slack](http://slack.kotlinlang.org/), channel: * :newspaper: [RSS Feed of articles, videos, slides, updates (full archive)](http://kotlin.link/rss-full.xml) -:octocat: [Awesome Kotlin - README.md](https://github.com/Heapy/awesome-kotlin/blob/readme/README.md) - README with links - ## Spread Awesome Kotlin! Here is the awesome badge for your project: diff --git a/app-backend-dataops/src/main/kotlin/Generate.kt b/app-backend-dataops/src/main/kotlin/Generate.kt index 74ae1db59..e69478983 100644 --- a/app-backend-dataops/src/main/kotlin/Generate.kt +++ b/app-backend-dataops/src/main/kotlin/Generate.kt @@ -30,7 +30,7 @@ fun drop() { fun flyway() { Flyway .configure() - .locations("filesystem:./app-backend/src/main/resources/db/migration/main") + .locations("filesystem:./app-backend/src/main/resources/infra/db/migration/main") .dataSource( "jdbc:postgresql://localhost:9567/awesome_kotlin", "awesome_kotlin", diff --git a/app-backend/Dockerfile b/app-backend/Dockerfile deleted file mode 100644 index 11b42fabc..000000000 --- a/app-backend/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM bellsoft/liberica-openjre-alpine:21.0.5 -RUN apk --no-cache add curl -COPY /build/install/awesome /app/ -ENTRYPOINT /app/bin/awesome diff --git a/app-backend/api-resources.http b/app-backend/api-resources.http new file mode 100644 index 000000000..142c122cb --- /dev/null +++ b/app-backend/api-resources.http @@ -0,0 +1,14 @@ +### Atom feed, 20 latest +GET {{host}}/rss.xml + +### Atom feed, all +GET {{host}}/rss-full.xml + +### Sitemap +GET {{host}}/sitemap.xml + +### Articles +GET {{host}}/articles + +### README.md +GET {{host}}/readme.md diff --git a/app-backend/api.http b/app-backend/api.http index 42b1698fb..68b946c3f 100644 --- a/app-backend/api.http +++ b/app-backend/api.http @@ -1,3 +1,4 @@ +### POST {{host}}/register Content-Type: application/json @@ -14,7 +15,6 @@ Content-Type: application/json } ### - POST {{host}}/login Content-Type: application/json @@ -30,25 +30,22 @@ Content-Type: application/json } ### - GET {{host}}/ ### - -GET {{host}}/ping/test - -### - GET {{host}}/kugs ### - POST {{host}}/kugs -### - -GET {{host}}/metrics-micrometer +### Prometheus Metrics +GET {{host}}/metrics -### +### Healthcheck +GET {{host}}/healthcheck +### Test GET {{host}}/test + +### Home Page +GET {{host}}/home diff --git a/app-backend/build.gradle.kts b/app-backend/build.gradle.kts index 9fe0f41aa..891f08c0a 100644 --- a/app-backend/build.gradle.kts +++ b/app-backend/build.gradle.kts @@ -1,5 +1,6 @@ plugins { application + alias(libs.plugins.ksp) alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.serialization) } @@ -13,17 +14,22 @@ repositories { mavenCentral() } -tasks.withType().configureEach { +kotlin { compilerOptions { freeCompilerArgs.addAll( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + "-Xcontext-receivers", ) } + + jvmToolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } } tasks.test { - useJUnitPlatform() + useJUnitPlatform { + includeTags("unit", "integration") + } } dependencies { @@ -34,6 +40,7 @@ dependencies { implementation(libs.kotlinx.serialization.json) implementation(libs.kotlinx.serialization.hocon) implementation(libs.kaml) + implementation(libs.xmlutil) implementation(libs.flyway.database.postgresql) implementation(libs.jooq.core) @@ -41,8 +48,20 @@ dependencies { implementation(libs.hikari) implementation("at.favre.lib:bcrypt:0.10.2") + implementation(libs.bouncycastle.bcpkix) + + implementation("com.rometools:rome:2.1.0") + + // todo: review this dependency + implementation("com.github.dfabulich:sitemapgen4j:1.1.2") + + implementation("org.commonmark:commonmark:0.24.0") + implementation("org.commonmark:commonmark-ext-gfm-tables:0.24.0") + + implementation("org.jsoup:jsoup:1.18.3") - implementation(libs.komok.tech.to.be.injected) + ksp(libs.komok.tech.di) + implementation(libs.komok.tech.di.lib) implementation(libs.komok.tech.config.dotenv) implementation(libs.komok.tech.logging) diff --git a/app-backend/docker-compose.dev.yml b/app-backend/docker-compose.dev.yml index 72f5c1254..341f8b68e 100644 --- a/app-backend/docker-compose.dev.yml +++ b/app-backend/docker-compose.dev.yml @@ -1,7 +1,7 @@ # docker-compose -f docker-compose.dev.yml up -d services: awesome_kotlin_database: - image: postgres:16.2 + image: postgres:17.2 container_name: awesome_kotlin_database restart: always mem_limit: 128m diff --git a/app-backend/src/main/kotlin/Application.kt b/app-backend/src/main/kotlin/Application.kt index d119e1e67..d012f6508 100644 --- a/app-backend/src/main/kotlin/Application.kt +++ b/app-backend/src/main/kotlin/Application.kt @@ -1,140 +1,6 @@ @file:JvmName("Application") -import io.heapy.komok.tech.di.delegate.bean -import usecases.github.GithubModule -import usecases.kug.KugModule -import usecases.links.LinksModule -import usecases.ping.PingModule -import usecases.signup.JwtModule -import usecases.signup.LoginModule -import usecases.signup.RegisterModule -import utils.close -import utils.logger -import java.lang.management.ManagementFactory -import java.lang.management.RuntimeMXBean -import kotlin.time.Duration.Companion.milliseconds - -suspend fun main() { - ApplicationFactory().use { - it.run() - } -} - -open class ApplicationFactory : AutoCloseable { - open val httpClientModule by lazy { - HttpClientModule() - } - - open val yamlModule by lazy { - YamlModule() - } - - open val configModule by lazy { - ConfigModule() - } - - open val jdbcModule by lazy { - JdbcModule( - configModule = configModule, - ) - } - - open val lifecycleModule by lazy { - LifecycleModule() - } - - open val jwtModule by lazy { - JwtModule( - configModule = configModule, - ) - } - - open val jooqModule by lazy { - JooqModule( - jdbcModule = jdbcModule, - ) - } - - open val flywayModule by lazy { - FlywayModule( - jdbcModule = jdbcModule, - ) - } - - open val loginModule by lazy { - LoginModule( - jooqModule = jooqModule, - jwtModule = jwtModule, - ) - } - - open val registerModule by lazy { - RegisterModule( - jooqModule = jooqModule, - ) - } - - open val kugModule by lazy { - KugModule( - httpClientModule = httpClientModule, - yamlModule = yamlModule, - jooqModule = jooqModule, - ) - } - - open val githubModule by lazy { - GithubModule( - configModule = configModule, - httpClientModule = httpClientModule, - ) - } - - open val pingModule by lazy { - PingModule() - } - - open val linksModule by lazy { - LinksModule() - } - - open val metricsModule by lazy { - MetricsModule() - } - - open val serverModule by lazy { - ServerModule( - githubModule = githubModule, - pingModule = pingModule, - loginModule = loginModule, - registerModule = registerModule, - linksModule = linksModule, - kugModule = kugModule, - jwtModule = jwtModule, - metricsModule = metricsModule, - lifecycleModule = lifecycleModule, - configModule = configModule, - ) - } - - open suspend fun run() { - val gracefulShutdown = lifecycleModule.gracefulShutdown.value - lifecycleModule.shutdownHandler.value.registerHook() - flywayModule.flyway.value.migrate() - serverModule.ktorServer.value.start(wait = false) - log.value.info("Server started in {}", runtimeMXBean.value.uptime.milliseconds) - gracefulShutdown.waitForShutdown() - } - - open val runtimeMXBean by bean { - ManagementFactory.getRuntimeMXBean() - } - - open val log by bean { - logger() - } - - override fun close() { - jdbcModule.close {} - httpClientModule.close {} - } +fun main() { + createApplicationModule {} + .use(ApplicationModule::run) } diff --git a/app-backend/src/main/kotlin/ApplicationModule.kt b/app-backend/src/main/kotlin/ApplicationModule.kt new file mode 100644 index 000000000..e317ab2e9 --- /dev/null +++ b/app-backend/src/main/kotlin/ApplicationModule.kt @@ -0,0 +1,43 @@ +import infra.db.FlywayModule +import infra.lifecycle.AutoClosableModule +import infra.lifecycle.LifecycleModule +import io.heapy.komok.tech.di.lib.Module +import io.heapy.komok.tech.logging.Logger +import kotlinx.coroutines.runBlocking +import server.KtorServerModule +import usecases.reload.LiveReloadModule +import usecases.stars_job.StarsJobModule +import java.lang.management.ManagementFactory +import java.lang.management.RuntimeMXBean +import kotlin.time.Duration.Companion.milliseconds + +@Module +open class ApplicationModule( + private val lifecycleModule: LifecycleModule, + private val starsJobModule: StarsJobModule, + private val flywayModule: FlywayModule, + private val ktorServerModule: KtorServerModule, + private val autoClosableModule: AutoClosableModule, + private val liveReloadModule: LiveReloadModule, +) : AutoCloseable { + fun run() = runBlocking { + val gracefulShutdown = lifecycleModule.gracefulShutdown + starsJobModule.starsJobScheduler.start() + lifecycleModule.shutdownHandler.registerHook() + flywayModule.flyway.migrate() + ktorServerModule.ktorServer.start(wait = false) + liveReloadModule.liveReloadService.start() + log.info("Server started in {}", runtimeMXBean.uptime.milliseconds) + gracefulShutdown.waitForShutdown() + } + + override fun close() { + autoClosableModule.close() + } + + open val runtimeMXBean: RuntimeMXBean by lazy { + ManagementFactory.getRuntimeMXBean() + } + + private companion object : Logger() +} diff --git a/app-backend/src/main/kotlin/ConfigModule.kt b/app-backend/src/main/kotlin/ConfigModule.kt deleted file mode 100644 index bf70615a4..000000000 --- a/app-backend/src/main/kotlin/ConfigModule.kt +++ /dev/null @@ -1,22 +0,0 @@ -import com.typesafe.config.Config -import com.typesafe.config.ConfigFactory -import config.dotenv -import io.heapy.komok.tech.di.delegate.bean - -open class ConfigModule { - open val overrides by bean { - mapOf() - } - - open val dotenv by bean { - dotenv() - } - - open val config by bean { - (overrides.value + dotenv.value).forEach { - System.setProperty(it.key, it.value) - } - - ConfigFactory.load() - } -} diff --git a/app-backend/src/main/kotlin/FlywayModule.kt b/app-backend/src/main/kotlin/FlywayModule.kt deleted file mode 100644 index d02bc4b2e..000000000 --- a/app-backend/src/main/kotlin/FlywayModule.kt +++ /dev/null @@ -1,13 +0,0 @@ -import io.heapy.komok.tech.di.delegate.bean -import org.flywaydb.core.Flyway - -open class FlywayModule( - private val jdbcModule: JdbcModule, -) { - open val flyway by bean { - Flyway.configure() - .locations("classpath:db/migration/main") - .dataSource(jdbcModule.dataSource.value) - .load() - } -} diff --git a/app-backend/src/main/kotlin/HttpClientModule.kt b/app-backend/src/main/kotlin/HttpClientModule.kt deleted file mode 100644 index b48df6bee..000000000 --- a/app-backend/src/main/kotlin/HttpClientModule.kt +++ /dev/null @@ -1,23 +0,0 @@ -import io.heapy.komok.tech.di.delegate.bean -import io.ktor.client.* -import io.ktor.client.engine.cio.* -import io.ktor.client.plugins.contentnegotiation.* -import io.ktor.serialization.kotlinx.json.* -import kotlinx.serialization.json.Json -import utils.close - -open class HttpClientModule : AutoCloseable { - open val httpClient by bean { - HttpClient(CIO) { - install(ContentNegotiation) { - json(json = Json { - ignoreUnknownKeys = true - }) - } - } - } - - override fun close() { - if (httpClient.isInitialized) httpClient.value.close {} - } -} diff --git a/app-backend/src/main/kotlin/LifecycleModule.kt b/app-backend/src/main/kotlin/LifecycleModule.kt deleted file mode 100644 index 49d7945ec..000000000 --- a/app-backend/src/main/kotlin/LifecycleModule.kt +++ /dev/null @@ -1,16 +0,0 @@ -import io.heapy.komok.tech.di.delegate.bean -import lifecycle.GracefulShutdown -import lifecycle.JvmShutdownManager -import lifecycle.ShutdownManager - -open class LifecycleModule { - open val shutdownHandler by bean { - JvmShutdownManager() - } - - open val gracefulShutdown by bean { - GracefulShutdown().also { - shutdownHandler.value.addHandler(it::shutdown) - } - } -} diff --git a/app-backend/src/main/kotlin/MetricsModule.kt b/app-backend/src/main/kotlin/MetricsModule.kt deleted file mode 100644 index a0435404f..000000000 --- a/app-backend/src/main/kotlin/MetricsModule.kt +++ /dev/null @@ -1,9 +0,0 @@ -import io.heapy.komok.tech.di.delegate.bean -import io.micrometer.prometheusmetrics.PrometheusConfig -import io.micrometer.prometheusmetrics.PrometheusMeterRegistry - -open class MetricsModule { - open val meterRegistry by bean { - PrometheusMeterRegistry(PrometheusConfig.DEFAULT) - } -} diff --git a/app-backend/src/main/kotlin/ServerModule.kt b/app-backend/src/main/kotlin/ServerModule.kt deleted file mode 100644 index b34c9f7aa..000000000 --- a/app-backend/src/main/kotlin/ServerModule.kt +++ /dev/null @@ -1,103 +0,0 @@ -import io.heapy.komok.tech.di.delegate.bean -import io.ktor.server.auth.* -import io.ktor.server.auth.jwt.* -import io.ktor.server.cio.* -import io.ktor.server.engine.* -import io.ktor.server.response.* -import io.ktor.server.routing.* -import kotlinx.serialization.Serializable -import kotlinx.serialization.hocon.Hocon -import kotlinx.serialization.hocon.decodeFromConfig -import ktor.plugins.configureMonitoring -import ktor.plugins.configureSockets -import ktor.plugins.defaults -import usecases.github.GithubModule -import usecases.kug.KugModule -import usecases.links.LinksModule -import usecases.ping.PingModule -import usecases.signup.JwtModule -import usecases.signup.LoginModule -import usecases.signup.RegisterModule -import utils.withEach -import kotlin.time.Duration - -open class ServerModule( - private val githubModule: GithubModule, - private val pingModule: PingModule, - private val loginModule: LoginModule, - private val registerModule: RegisterModule, - private val linksModule: LinksModule, - private val kugModule: KugModule, - private val jwtModule: JwtModule, - private val metricsModule: MetricsModule, - private val lifecycleModule: LifecycleModule, - private val configModule: ConfigModule, -) { - open val unauthenticatedRoutes by bean { - listOf( - githubModule.githubRedirectRoute.value, - githubModule.githubCallbackRoute.value, - - pingModule.route.value, - - loginModule.route.value, - registerModule.route.value, - - linksModule.route.value, - kugModule.getKugRoute.value, - kugModule.updateKugsRoute.value, - ) - } - - open val ktorServer by bean { - System.setProperty("io.ktor.server.engine.ShutdownHook", "false") - - val unauthenticatedRoutes = unauthenticatedRoutes.value - val jwtConfig = jwtModule.jwtConfig.value - val serverConfig = serverConfig.value - val meterRegistry = metricsModule.meterRegistry.value - - embeddedServer( - factory = CIO, - port = serverConfig.port, - host = serverConfig.host, - ) { - defaults(jwtConfig) - - routing { - unauthenticatedRoutes.withEach { - install() - } - - authenticate("jwt") { - get("/test") { - val principal = call.principal() - principal?.getClaim("id", Long::class)?.let { id -> - call.respond("Hello, $id!") - } ?: call.respond("Hello, world!") - } - } - } - configureSockets() - configureMonitoring(meterRegistry) - }.also { server -> - lifecycleModule.shutdownHandler.value.addHandler { - server.stop( - gracePeriodMillis = serverConfig.gracefulShutdownTimeout.inWholeMilliseconds, - timeoutMillis = 5000, - ) - } - } - } - - open val serverConfig by bean { - Hocon.decodeFromConfig(configModule.config.value.getConfig("server")) - } - - @Serializable - data class ServerConfig( - val port: Int, - val host: String, - val gracefulShutdownTimeout: Duration, - ) -} diff --git a/app-backend/src/main/kotlin/XmlModule.kt b/app-backend/src/main/kotlin/XmlModule.kt deleted file mode 100644 index 942fab6f9..000000000 --- a/app-backend/src/main/kotlin/XmlModule.kt +++ /dev/null @@ -1,11 +0,0 @@ -import com.fasterxml.jackson.dataformat.xml.XmlMapper -import com.fasterxml.jackson.module.kotlin.kotlinModule -import io.heapy.komok.tech.di.delegate.bean - -open class XmlModule { - open val xmlMapper by bean { - XmlMapper().apply { - registerModule(kotlinModule { }) - } - } -} diff --git a/app-backend/src/main/kotlin/YamlModule.kt b/app-backend/src/main/kotlin/YamlModule.kt deleted file mode 100644 index ca2f2db6d..000000000 --- a/app-backend/src/main/kotlin/YamlModule.kt +++ /dev/null @@ -1,8 +0,0 @@ -import com.charleskorn.kaml.Yaml -import io.heapy.komok.tech.di.delegate.bean - -open class YamlModule { - open val yaml by bean { - Yaml.default - } -} diff --git a/app-backend/src/main/kotlin/config/dotenv.kt b/app-backend/src/main/kotlin/config/dotenv.kt deleted file mode 100644 index c83400736..000000000 --- a/app-backend/src/main/kotlin/config/dotenv.kt +++ /dev/null @@ -1,37 +0,0 @@ -package config - -import java.nio.file.Path -import java.nio.file.Paths -import kotlin.io.path.exists -import kotlin.io.path.readLines - -fun dotenv(): Map { - return resolveEnv(Paths.get(".").toAbsolutePath().normalize()) - ?.let { envPath -> - envPath.readLines() - .filter(String::isNotBlank) - .filter { !it.startsWith("#") } - .associate { - val split = it.split("=", limit = 2) - if (split.size != 2) error("Line syntax: key=value, got: $it") - split[0].trim() to split[1].trim() - } - } - ?: emptyMap() -} - -private fun resolveEnv(root: Path): Path? { - return root.resolve(".env").let { envPath -> - if (envPath.exists()) { - envPath - } else { - if (envPath.parent == null) { - null - } else if (envPath.parent.resolve(".git").exists()) { - null - } else { - resolveEnv(root = root.parent) - } - } - } -} diff --git a/app-backend/src/main/kotlin/infra/HttpClientModule.kt b/app-backend/src/main/kotlin/infra/HttpClientModule.kt new file mode 100644 index 000000000..8e6e5fcce --- /dev/null +++ b/app-backend/src/main/kotlin/infra/HttpClientModule.kt @@ -0,0 +1,31 @@ +package infra + +import io.heapy.komok.tech.di.lib.Module +import io.ktor.client.* +import io.ktor.client.engine.cio.* +import io.ktor.client.plugins.contentnegotiation.* +import io.ktor.serialization.kotlinx.json.* +import kotlinx.serialization.json.Json +import infra.lifecycle.AutoClosableModule + +@Module +open class HttpClientModule( + private val autoClosableModule: AutoClosableModule, +) { + open val httpClient by lazy { + val httpClient = HttpClient(engineFactory = CIO) { + install(ContentNegotiation) { + json(json = Json { + ignoreUnknownKeys = true + }) + } + } + + autoClosableModule.addClosable( + t = httpClient, + close = HttpClient::close, + ) + + httpClient + } +} diff --git a/app-backend/src/main/kotlin/infra/cache/CacheBuilder.kt b/app-backend/src/main/kotlin/infra/cache/CacheBuilder.kt new file mode 100644 index 000000000..c8edb04a8 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/cache/CacheBuilder.kt @@ -0,0 +1,10 @@ +package infra.cache + +import kotlin.time.Duration + +interface CacheBuilder { + fun expireAfterWrite(duration: Duration) + fun timeout(duration: Duration) + fun loader(body: suspend (K) -> V) + fun build(): LoadingCache +} diff --git a/app-backend/src/main/kotlin/infra/cache/LoadingCache.kt b/app-backend/src/main/kotlin/infra/cache/LoadingCache.kt new file mode 100644 index 000000000..9fc2432b3 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/cache/LoadingCache.kt @@ -0,0 +1,44 @@ +package infra.cache + +import kotlin.time.Duration + +interface LoadingCache { + suspend fun get(key: K): V +} + +fun buildCache( + builder: CacheBuilder.() -> Unit, +): LoadingCache { + val cacheBuilder = object : CacheBuilder { + private var expireAfterWrite: Duration? = null + private var timeout: Duration? = null + private var loader: (suspend (K) -> V)? = null + + override fun expireAfterWrite(duration: Duration) { + expireAfterWrite = duration + } + + override fun timeout(duration: Duration) { + timeout = duration + } + + override fun loader(body: suspend (K) -> V) { + loader = body + } + + override fun build(): LoadingCache { + val loader = loader ?: error("loader is not set") + val expireAfterWrite = expireAfterWrite ?: error("expireAfterWrite is not set") + val timeout = timeout ?: error("timeout is not set") + + return SimpleLoadingCache( + loader = loader, + expireAfterWrite = expireAfterWrite, + timeout = timeout, + ) + } + } + + return cacheBuilder.apply(builder).build() +} + diff --git a/app-backend/src/main/kotlin/infra/cache/SimpleLoadingCache.kt b/app-backend/src/main/kotlin/infra/cache/SimpleLoadingCache.kt new file mode 100644 index 000000000..549983dc3 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/cache/SimpleLoadingCache.kt @@ -0,0 +1,50 @@ +package infra.cache + +import kotlinx.coroutines.* +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import java.time.Instant +import kotlin.time.Duration +import kotlin.time.Duration.Companion.minutes + +internal class SimpleLoadingCache( + private val loader: suspend (K) -> V, + private val expireAfterWrite: Duration = 5.minutes, + private val timeout: Duration = 1.minutes, +) : LoadingCache { + private data class CacheEntry( + val value: Deferred, + val expirationTime: Long, + ) + + private val store = mutableMapOf>() + private val mutex = Mutex() + private val job = SupervisorJob() + + private fun instant(): Long { + return Instant.now().epochSecond + } + + override suspend fun get(key: K): V { + val deferred = mutex.withLock { + val entry = store[key]?.takeIf { it.expirationTime > instant() } + + if (entry == null) { + val newDeferred = CoroutineScope(job).async { + withTimeout(timeout) { + loader(key) + } + } + store[key] = CacheEntry( + value = newDeferred, + expirationTime = instant() + expireAfterWrite.inWholeSeconds, + ) + newDeferred + } else { + entry.value + } + } + + return deferred.await() + } +} diff --git a/app-backend/src/main/kotlin/infra/config/ConfigModule.kt b/app-backend/src/main/kotlin/infra/config/ConfigModule.kt new file mode 100644 index 000000000..8b188d66b --- /dev/null +++ b/app-backend/src/main/kotlin/infra/config/ConfigModule.kt @@ -0,0 +1,44 @@ +package infra.config + +import com.typesafe.config.Config +import com.typesafe.config.ConfigFactory +import io.heapy.komok.tech.config.dotenv.dotenv +import io.heapy.komok.tech.di.lib.Module +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.KSerializer +import kotlinx.serialization.hocon.Hocon + +@Module +open class ConfigModule { + open val overrides by lazy { + mapOf() + } + + open val dotenv by lazy { + dotenv() + } + + open val env by lazy { + buildMap { + putAll(System.getenv()) + putAll(dotenv.properties) + putAll(overrides) + } + } + + open val config: Config by lazy { + env.forEach { + System.setProperty(it.key, it.value) + } + + ConfigFactory.load() + } +} + +@OptIn(ExperimentalSerializationApi::class) +fun ConfigModule.decode( + path: String, + deserializer: KSerializer, +): T { + return Hocon.decodeFromConfig(deserializer, config.getConfig(path)) +} diff --git a/app-backend/src/main/kotlin/infra/db/FlywayModule.kt b/app-backend/src/main/kotlin/infra/db/FlywayModule.kt new file mode 100644 index 000000000..d418580c2 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/db/FlywayModule.kt @@ -0,0 +1,16 @@ +package infra.db + +import io.heapy.komok.tech.di.lib.Module +import org.flywaydb.core.Flyway + +@Module +open class FlywayModule( + private val jdbcModule: JdbcModule, +) { + open val flyway: Flyway by lazy { + Flyway.configure() + .locations("classpath:infra/db/migration/main") + .dataSource(jdbcModule.dataSource) + .load() + } +} diff --git a/app-backend/src/main/kotlin/JdbcModule.kt b/app-backend/src/main/kotlin/infra/db/JdbcModule.kt similarity index 54% rename from app-backend/src/main/kotlin/JdbcModule.kt rename to app-backend/src/main/kotlin/infra/db/JdbcModule.kt index 562f73573..aaeba9d29 100644 --- a/app-backend/src/main/kotlin/JdbcModule.kt +++ b/app-backend/src/main/kotlin/infra/db/JdbcModule.kt @@ -1,29 +1,41 @@ +package infra.db + import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource -import io.heapy.komok.tech.di.delegate.bean +import infra.config.ConfigModule +import infra.config.decode +import io.heapy.komok.tech.di.lib.Module import kotlinx.serialization.Serializable -import kotlinx.serialization.hocon.Hocon -import kotlinx.serialization.hocon.decodeFromConfig -import utils.close +import infra.lifecycle.AutoClosableModule +@Module open class JdbcModule( private val configModule: ConfigModule, -) : AutoCloseable { - open val dataSource by bean { - HikariDataSource( + private val autoClosableModule: AutoClosableModule, +) { + open val dataSource by lazy { + val dataSource = HikariDataSource( HikariConfig().also { + it.poolName = "Awesome Kotlin Pool" it.dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource" it.username = "awesome_kotlin" it.password = "awesome_kotlin" it.addDataSourceProperty("databaseName", "awesome_kotlin") - it.addDataSourceProperty("serverName", jdbcConfig.value.host) - it.addDataSourceProperty("portNumber", jdbcConfig.value.port) + it.addDataSourceProperty("serverName", jdbcConfig.host) + it.addDataSourceProperty("portNumber", jdbcConfig.port) } ) + + autoClosableModule.addClosable( + t = dataSource, + close = HikariDataSource::close, + ) + + dataSource } - open val jdbcConfig by bean { - Hocon.decodeFromConfig(configModule.config.value.getConfig("jdbc")) + open val jdbcConfig: JdbcConfig by lazy { + configModule.decode("jdbc", JdbcConfig.serializer()) } @Serializable @@ -31,8 +43,4 @@ open class JdbcModule( val host: String, val port: String, ) - - override fun close() { - if (dataSource.isInitialized) dataSource.value.close {} - } } diff --git a/app-backend/src/main/kotlin/JooqModule.kt b/app-backend/src/main/kotlin/infra/db/JooqModule.kt similarity index 59% rename from app-backend/src/main/kotlin/JooqModule.kt rename to app-backend/src/main/kotlin/infra/db/JooqModule.kt index 924377c23..7ff66ad19 100644 --- a/app-backend/src/main/kotlin/JooqModule.kt +++ b/app-backend/src/main/kotlin/infra/db/JooqModule.kt @@ -1,13 +1,16 @@ -import io.heapy.komok.tech.di.delegate.bean +package infra.db + +import io.heapy.komok.tech.di.lib.Module import org.jooq.SQLDialect import org.jooq.impl.DSL +@Module open class JooqModule( private val jdbcModule: JdbcModule, ) { - open val dslContext by bean { + open val dslContext by lazy { System.setProperty("org.jooq.no-logo", "true") System.setProperty("org.jooq.no-tips", "true") - DSL.using(jdbcModule.dataSource.value, SQLDialect.POSTGRES) + DSL.using(jdbcModule.dataSource, SQLDialect.POSTGRES) } } diff --git a/app-backend/src/main/kotlin/infra/file_watcher/FileMonitor.kt b/app-backend/src/main/kotlin/infra/file_watcher/FileMonitor.kt new file mode 100644 index 000000000..6a7222cce --- /dev/null +++ b/app-backend/src/main/kotlin/infra/file_watcher/FileMonitor.kt @@ -0,0 +1,49 @@ +package infra.file_watcher + +import io.heapy.komok.tech.logging.Logger +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.Channel +import java.nio.file.FileSystems +import java.nio.file.Path +import java.nio.file.StandardWatchEventKinds.* +import java.nio.file.WatchKey +import java.nio.file.WatchService + +class FileMonitor { + private val job = SupervisorJob() + + fun monitor(folder: Path): Channel { + val watchService: WatchService = FileSystems.getDefault().newWatchService() + + // Register the folder with the watch service for the events we want to monitor + folder.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY) + + val channel = Channel() + + CoroutineScope(job).launch(Dispatchers.IO) { + while (true) { + val key: WatchKey = watchService.take() // Blocks until events are available + + log.info("Received watch key: $key") + + for (event in key.pollEvents()) { + log.info("Received watch event: $event") + + val kind = event.kind() + + channel.send(kind.name()) + } + + val valid = key.reset() + if (!valid) { + log.error("Watch key is no longer valid") + break + } + } + } + + return channel + } + + private companion object : Logger() +} diff --git a/app-backend/src/main/kotlin/infra/file_watcher/FileMonitorModule.kt b/app-backend/src/main/kotlin/infra/file_watcher/FileMonitorModule.kt new file mode 100644 index 000000000..3528421d7 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/file_watcher/FileMonitorModule.kt @@ -0,0 +1,10 @@ +package infra.file_watcher + +import io.heapy.komok.tech.di.lib.Module + +@Module +open class FileMonitorModule { + open val fileMonitor by lazy { + FileMonitor() + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/KtorFeature.kt b/app-backend/src/main/kotlin/infra/ktor/KtorFeature.kt new file mode 100644 index 000000000..3dd720959 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/KtorFeature.kt @@ -0,0 +1,7 @@ +package infra.ktor + +import io.ktor.server.application.* + +interface KtorFeature { + fun Application.install() +} diff --git a/app-backend/src/main/kotlin/infra/ktor/KtorFeaturesModule.kt b/app-backend/src/main/kotlin/infra/ktor/KtorFeaturesModule.kt new file mode 100644 index 000000000..3050b19d3 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/KtorFeaturesModule.kt @@ -0,0 +1,66 @@ +package infra.ktor + +import infra.ktor.features.* +import io.heapy.komok.tech.di.lib.Module +import infra.metrics.MetricsModule +import usecases.reload.NotificationChannelModule +import usecases.signup.JwtModule + +@Module +open class KtorFeaturesModule( + private val jwtModule: JwtModule, + private val metricsModule: MetricsModule, + private val notificationChannelModule: NotificationChannelModule, +) { + open val authenticationFeature by lazy { + AuthenticationFeature( + jwtConfig = jwtModule.jwtConfig, + ) + } + + open val cachingFeature by lazy { + CachingFeature() + } + + open val contentNegotiationFeature by lazy { + ContentNegotiationFeature() + } + + open val resourcesFeature by lazy { + ResourcesFeature() + } + + open val statusPageFeature by lazy { + StatusPageFeature() + } + + open val webSocketsFeature by lazy { + WebSocketsFeature( + notificationChannel = notificationChannelModule.notificationChannel, + ) + } + + open val callLoggingFeature by lazy { + CallLoggingFeature() + } + + open val metricsFeature by lazy { + MetricsFeature( + meterRegistry = metricsModule.meterRegistry, + binders = metricsModule.binders, + ) + } + + open val features by lazy { + listOf( + authenticationFeature, + cachingFeature, + contentNegotiationFeature, + resourcesFeature, + statusPageFeature, + callLoggingFeature, + metricsFeature, + webSocketsFeature, + ) + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/KtorRoute.kt b/app-backend/src/main/kotlin/infra/ktor/KtorRoute.kt new file mode 100644 index 000000000..c623483fc --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/KtorRoute.kt @@ -0,0 +1,16 @@ +@file:Suppress("CONTEXT_RECEIVERS_DEPRECATED") + +package infra.ktor + +import io.ktor.server.routing.Route + +interface KtorRoute { + fun Route.install() +} + +context(Route) +fun KtorRoute.installRoute() { + with(this) { + install() + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/features/AuthenticationFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/AuthenticationFeature.kt new file mode 100644 index 000000000..1aeb1b2e0 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/AuthenticationFeature.kt @@ -0,0 +1,53 @@ +package infra.ktor.features + +import com.auth0.jwt.JWT +import com.auth0.jwt.algorithms.Algorithm +import io.heapy.komok.tech.logging.logger +import io.ktor.http.auth.* +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.auth.jwt.* +import infra.ktor.KtorFeature +import io.heapy.komok.tech.logging.Logger +import usecases.signup.JwtModule + +class AuthenticationFeature( + private val jwtConfig: JwtModule.JwtConfig, +) : KtorFeature { + override fun Application.install() { + authentication { + jwt("jwt") { + realm = jwtConfig.realm + authHeader { call -> + try { + call.request.cookies["token"] + ?.let { cookieValue -> + parseAuthorizationHeader("Bearer $cookieValue") + } + } catch (cause: IllegalArgumentException) { + logger.info("Failed to parse JWT from cookie", cause) + null + } + } + verifier( + JWT + .require(Algorithm.HMAC512(jwtConfig.secret)) + .withAudience(jwtConfig.audience) + .withIssuer(jwtConfig.issuer) + .build() + ) + validate { credential -> + if (credential.payload.audience.contains(jwtConfig.audience)) { + JWTPrincipal(credential.payload) + } else { + null + } + } + } + } + } + + private companion object : Logger() { + val logger = log + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/features/CachingFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/CachingFeature.kt new file mode 100644 index 000000000..d57d797fe --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/CachingFeature.kt @@ -0,0 +1,42 @@ +package infra.ktor.features + +import io.ktor.http.* +import io.ktor.http.content.* +import io.ktor.server.application.* +import io.ktor.server.plugins.cachingheaders.* +import infra.ktor.KtorFeature +import kotlin.time.Duration.Companion.days + +class CachingFeature : KtorFeature { + override fun Application.install() { + install(CachingHeaders) { + options { _, outgoingContent -> + when (outgoingContent.contentType?.withoutParameters()) { + ContentType.Text.CSS -> CachingOptions( + CacheControl.MaxAge( + maxAgeSeconds = 365.days + .inWholeSeconds + .toInt() + ) + ) + ContentType.Image.Any -> CachingOptions( + CacheControl.MaxAge( + maxAgeSeconds = 365.days + .inWholeSeconds + .toInt() + ) + ) + ContentType.Application.JavaScript -> CachingOptions( + CacheControl.MaxAge( + maxAgeSeconds = 365.days + .inWholeSeconds + .toInt() + ) + ) + + else -> null + } + } + } + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/features/CallLoggingFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/CallLoggingFeature.kt new file mode 100644 index 000000000..5b646519b --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/CallLoggingFeature.kt @@ -0,0 +1,16 @@ +package infra.ktor.features + +import io.ktor.server.application.* +import io.ktor.server.plugins.calllogging.* +import io.ktor.server.request.* +import infra.ktor.KtorFeature +import org.slf4j.event.Level + +class CallLoggingFeature : KtorFeature { + override fun Application.install() { + install(CallLogging) { + level = Level.INFO + filter { call -> call.request.path().startsWith("/") } + } + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/features/ContentNegotiationFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/ContentNegotiationFeature.kt new file mode 100644 index 000000000..e6e5ac60b --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/ContentNegotiationFeature.kt @@ -0,0 +1,14 @@ +package infra.ktor.features + +import io.ktor.serialization.kotlinx.json.* +import io.ktor.server.application.* +import io.ktor.server.plugins.contentnegotiation.* +import infra.ktor.KtorFeature + +class ContentNegotiationFeature : KtorFeature { + override fun Application.install() { + install(ContentNegotiation) { + json() + } + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/features/MetricsFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/MetricsFeature.kt new file mode 100644 index 000000000..c0dcf494d --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/MetricsFeature.kt @@ -0,0 +1,19 @@ +package infra.ktor.features + +import io.ktor.server.application.* +import io.ktor.server.metrics.micrometer.* +import io.micrometer.core.instrument.binder.MeterBinder +import io.micrometer.prometheusmetrics.PrometheusMeterRegistry +import infra.ktor.KtorFeature + +class MetricsFeature( + private val meterRegistry: PrometheusMeterRegistry, + private val binders: List, +) : KtorFeature { + override fun Application.install() { + install(MicrometerMetrics) { + registry = meterRegistry + meterBinders = binders + } + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/features/ResourcesFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/ResourcesFeature.kt new file mode 100644 index 000000000..a5876bf35 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/ResourcesFeature.kt @@ -0,0 +1,11 @@ +package infra.ktor.features + +import io.ktor.server.application.* +import io.ktor.server.resources.* +import infra.ktor.KtorFeature + +class ResourcesFeature : KtorFeature { + override fun Application.install() { + install(Resources) + } +} diff --git a/app-backend/src/main/kotlin/infra/ktor/features/StatusPageFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/StatusPageFeature.kt new file mode 100644 index 000000000..baf45f25a --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/StatusPageFeature.kt @@ -0,0 +1,39 @@ +package infra.ktor.features + +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.plugins.statuspages.* +import io.ktor.server.response.* +import kotlinx.serialization.Serializable +import infra.ktor.KtorFeature + +class StatusPageFeature : KtorFeature { + override fun Application.install() { + install(StatusPages) { + exception { call, _ -> + call.respond(HttpStatusCode.Unauthorized) + } + exception { call, _ -> + call.respond(HttpStatusCode.Forbidden) + } + exception { call, cause -> + call.respond(HttpStatusCode.BadRequest, cause.fields) + } + } + } +} + +class AuthenticationException : RuntimeException() + +class AuthorizationException : RuntimeException() + +class ConstraintViolationException( + val fields: List, +) : RuntimeException() + +@Serializable +data class ConstraintViolationFields( + val message: String, + val fields: List, +) + diff --git a/app-backend/src/main/kotlin/infra/ktor/features/WebSocketsFeature.kt b/app-backend/src/main/kotlin/infra/ktor/features/WebSocketsFeature.kt new file mode 100644 index 000000000..a86c97b9e --- /dev/null +++ b/app-backend/src/main/kotlin/infra/ktor/features/WebSocketsFeature.kt @@ -0,0 +1,41 @@ +package infra.ktor.features + +import infra.ktor.KtorFeature +import io.heapy.komok.tech.logging.Logger +import io.ktor.server.application.* +import io.ktor.server.routing.* +import io.ktor.server.websocket.* +import io.ktor.websocket.* +import usecases.reload.NotificationChannel +import kotlin.time.Duration.Companion.seconds + +class WebSocketsFeature( + private val notificationChannel: NotificationChannel, +) : KtorFeature { + override fun Application.install() { + install(WebSockets) { + pingPeriod = 15.seconds + timeout = 15.seconds + maxFrameSize = Long.MAX_VALUE + masking = false + } + + routing { + webSocket("/api/ws") { + log.info("WebSocket connection established from $call") + notificationChannel.register(outgoing) + for (frame in incoming) { + when (frame) { + is Frame.Text -> { + val text = frame.readText() + log.info("Received: $text") + } + else -> {} + } + } + } + } + } + + private companion object : Logger() +} diff --git a/app-backend/src/main/kotlin/infra/lifecycle/AutoClosableModule.kt b/app-backend/src/main/kotlin/infra/lifecycle/AutoClosableModule.kt new file mode 100644 index 000000000..245d4bb00 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/lifecycle/AutoClosableModule.kt @@ -0,0 +1,36 @@ +package infra.lifecycle + +import io.heapy.komok.tech.di.lib.Module +import io.heapy.komok.tech.logging.Logger + +@Module +open class AutoClosableModule : AutoCloseable { + private val closable = mutableListOf<() -> Unit>() + + fun addClosable( + t: T, + close: (T) -> Unit, + ): T { + log.info("Adding closable $t") + closable.add { + log.info("Closing $t") + close(t) + log.info("Closed $t") + } + return t + } + + override fun close() { + closable + .reversed() + .forEach { closeFunction -> + try { + closeFunction() + } catch (e: Exception) { + log.error("Error while closing resource", e) + } + } + } + + private companion object : Logger() +} diff --git a/app-backend/src/main/kotlin/lifecycle/GracefulShutdown.kt b/app-backend/src/main/kotlin/infra/lifecycle/GracefulShutdown.kt similarity index 91% rename from app-backend/src/main/kotlin/lifecycle/GracefulShutdown.kt rename to app-backend/src/main/kotlin/infra/lifecycle/GracefulShutdown.kt index 1d50da2d6..c2c57ae22 100644 --- a/app-backend/src/main/kotlin/lifecycle/GracefulShutdown.kt +++ b/app-backend/src/main/kotlin/infra/lifecycle/GracefulShutdown.kt @@ -1,4 +1,4 @@ -package lifecycle +package infra.lifecycle import kotlinx.coroutines.CompletableDeferred diff --git a/app-backend/src/main/kotlin/infra/lifecycle/LifecycleModule.kt b/app-backend/src/main/kotlin/infra/lifecycle/LifecycleModule.kt new file mode 100644 index 000000000..6c6a0abc0 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/lifecycle/LifecycleModule.kt @@ -0,0 +1,25 @@ +package infra.lifecycle + +import io.heapy.komok.tech.di.lib.Module +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob + +@Module +open class LifecycleModule { + open val shutdownHandler by lazy { + JvmShutdownManager() + } + + open val gracefulShutdown by lazy { + GracefulShutdown().also { + shutdownHandler.addHandler(it::shutdown) + } + } + + open val applicationScope by lazy { + val job = SupervisorJob() + CoroutineScope(job).also { + shutdownHandler.addHandler { job.cancel() } + } + } +} diff --git a/app-backend/src/main/kotlin/lifecycle/ShutdownManager.kt b/app-backend/src/main/kotlin/infra/lifecycle/ShutdownManager.kt similarity index 87% rename from app-backend/src/main/kotlin/lifecycle/ShutdownManager.kt rename to app-backend/src/main/kotlin/infra/lifecycle/ShutdownManager.kt index 7a8b96c9e..fc5f86e75 100644 --- a/app-backend/src/main/kotlin/lifecycle/ShutdownManager.kt +++ b/app-backend/src/main/kotlin/infra/lifecycle/ShutdownManager.kt @@ -1,7 +1,7 @@ -package lifecycle +package infra.lifecycle +import io.heapy.komok.tech.logging.Logger import kotlinx.coroutines.runBlocking -import utils.logger import kotlin.concurrent.thread interface ShutdownManager { @@ -35,7 +35,5 @@ class JvmShutdownManager : ShutdownManager { }) } - private companion object { - private val log = logger() - } + private companion object : Logger() } diff --git a/app-backend/src/main/kotlin/infra/metrics/MetricsModule.kt b/app-backend/src/main/kotlin/infra/metrics/MetricsModule.kt new file mode 100644 index 000000000..8a66f56f1 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/metrics/MetricsModule.kt @@ -0,0 +1,45 @@ +package infra.metrics + +import infra.db.JdbcModule +import io.heapy.komok.tech.di.lib.Module +import io.micrometer.core.instrument.binder.db.PostgreSQLDatabaseMetrics +import io.micrometer.core.instrument.binder.jvm.* +import io.micrometer.core.instrument.binder.logging.LogbackMetrics +import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics +import io.micrometer.core.instrument.binder.system.ProcessorMetrics +import io.micrometer.core.instrument.binder.system.UptimeMetrics +import io.micrometer.prometheusmetrics.PrometheusConfig +import io.micrometer.prometheusmetrics.PrometheusMeterRegistry + +@Module +open class MetricsModule( + private val jdbcModule: JdbcModule, +) { + open val meterRegistry by lazy { + PrometheusMeterRegistry(PrometheusConfig.DEFAULT) + } + + open val binders by lazy { + listOf( + ClassLoaderMetrics(), + JvmMemoryMetrics(), + JvmGcMetrics(), + JvmHeapPressureMetrics(), + ProcessorMetrics(), + JvmThreadMetrics(), + FileDescriptorMetrics(), + UptimeMetrics(), + LogbackMetrics(), + PostgreSQLDatabaseMetrics( + jdbcModule.dataSource, + "awesome_kotlin" + ), + ) + } + + open val route by lazy { + MetricsRoute( + meterRegistry = meterRegistry, + ) + } +} diff --git a/app-backend/src/main/kotlin/infra/metrics/MetricsRoute.kt b/app-backend/src/main/kotlin/infra/metrics/MetricsRoute.kt new file mode 100644 index 000000000..fc70d77c3 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/metrics/MetricsRoute.kt @@ -0,0 +1,22 @@ +package infra.metrics + +import io.ktor.http.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import io.micrometer.prometheusmetrics.PrometheusMeterRegistry +import infra.ktor.KtorRoute + +class MetricsRoute( + private val meterRegistry: PrometheusMeterRegistry, +) : KtorRoute { + override fun Route.install() { + get("/metrics") { + call.respondText( + text = meterRegistry.scrape(), + contentType = ContentType.Text.Plain + .withCharset(Charsets.UTF_8) + .withParameter("version", "0.0.4"), + ) + } + } +} diff --git a/app-backend/src/main/kotlin/serialization/TimeSerializers.kt b/app-backend/src/main/kotlin/infra/serialization/TimeSerializers.kt similarity index 98% rename from app-backend/src/main/kotlin/serialization/TimeSerializers.kt rename to app-backend/src/main/kotlin/infra/serialization/TimeSerializers.kt index 0efd3e1e1..dd9ad29d8 100644 --- a/app-backend/src/main/kotlin/serialization/TimeSerializers.kt +++ b/app-backend/src/main/kotlin/infra/serialization/TimeSerializers.kt @@ -1,4 +1,4 @@ -package serialization +package infra.serialization import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind diff --git a/app-backend/src/main/kotlin/infra/serialization/XmlModule.kt b/app-backend/src/main/kotlin/infra/serialization/XmlModule.kt new file mode 100644 index 000000000..63104a9d5 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/serialization/XmlModule.kt @@ -0,0 +1,11 @@ +package infra.serialization + +import io.heapy.komok.tech.di.lib.Module +import nl.adaptivity.xmlutil.serialization.XML + +@Module +open class XmlModule { + open val xml: XML by lazy { + XML {} + } +} diff --git a/app-backend/src/main/kotlin/infra/serialization/YamlModule.kt b/app-backend/src/main/kotlin/infra/serialization/YamlModule.kt new file mode 100644 index 000000000..9266f8689 --- /dev/null +++ b/app-backend/src/main/kotlin/infra/serialization/YamlModule.kt @@ -0,0 +1,11 @@ +package infra.serialization + +import com.charleskorn.kaml.Yaml +import io.heapy.komok.tech.di.lib.Module + +@Module +open class YamlModule { + open val yaml by lazy { + Yaml.default + } +} diff --git a/app-backend/src/main/kotlin/utils/collections.kt b/app-backend/src/main/kotlin/infra/utils/collections.kt similarity index 84% rename from app-backend/src/main/kotlin/utils/collections.kt rename to app-backend/src/main/kotlin/infra/utils/collections.kt index 9a0c49faf..b36522450 100644 --- a/app-backend/src/main/kotlin/utils/collections.kt +++ b/app-backend/src/main/kotlin/infra/utils/collections.kt @@ -1,4 +1,4 @@ -package utils +package infra.utils inline fun Iterable.withEach(action: T.() -> Unit) { for (element in this) action(element) diff --git a/app-backend/src/main/kotlin/jooq/main/DefaultCatalog.kt b/app-backend/src/main/kotlin/jooq/main/DefaultCatalog.kt index eb62c8b45..afbe14585 100644 --- a/app-backend/src/main/kotlin/jooq/main/DefaultCatalog.kt +++ b/app-backend/src/main/kotlin/jooq/main/DefaultCatalog.kt @@ -21,7 +21,7 @@ open class DefaultCatalog : CatalogImpl("") { /** * The reference instance of DEFAULT_CATALOG */ - public val DEFAULT_CATALOG: DefaultCatalog = DefaultCatalog() + val DEFAULT_CATALOG: DefaultCatalog = DefaultCatalog() } /** diff --git a/app-backend/src/main/kotlin/jooq/main/Public.kt b/app-backend/src/main/kotlin/jooq/main/Public.kt index 0860b1b44..4ceba5882 100644 --- a/app-backend/src/main/kotlin/jooq/main/Public.kt +++ b/app-backend/src/main/kotlin/jooq/main/Public.kt @@ -22,6 +22,7 @@ import jooq.main.tables.CourseSpeaker import jooq.main.tables.DmLikes import jooq.main.tables.EntityTopic import jooq.main.tables.FlywaySchemaHistory +import jooq.main.tables.GithubAuth import jooq.main.tables.KotlinVersion import jooq.main.tables.Kotliner import jooq.main.tables.KotlinerLikeEntityState @@ -51,7 +52,7 @@ import org.jooq.impl.SchemaImpl */ @Suppress("UNCHECKED_CAST") open class Public : SchemaImpl("public", DefaultCatalog.DEFAULT_CATALOG) { - public companion object { + companion object { /** * The reference instance of public @@ -144,6 +145,11 @@ open class Public : SchemaImpl("public", DefaultCatalog.DEFAULT_CATALOG) { */ val FLYWAY_SCHEMA_HISTORY: FlywaySchemaHistory get() = FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY + /** + * The table public.github_auth. + */ + val GITHUB_AUTH: GithubAuth get() = GithubAuth.GITHUB_AUTH + /** * The table public.kotlin_version. */ @@ -243,6 +249,7 @@ open class Public : SchemaImpl("public", DefaultCatalog.DEFAULT_CATALOG) { DmLikes.DM_LIKES, EntityTopic.ENTITY_TOPIC, FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY, + GithubAuth.GITHUB_AUTH, KotlinVersion.KOTLIN_VERSION, Kotliner.KOTLINER, KotlinerLikeEntityState.KOTLINER_LIKE_ENTITY_STATE, diff --git a/app-backend/src/main/kotlin/jooq/main/keys/Keys.kt b/app-backend/src/main/kotlin/jooq/main/keys/Keys.kt index 0950f76db..90496cc0e 100644 --- a/app-backend/src/main/kotlin/jooq/main/keys/Keys.kt +++ b/app-backend/src/main/kotlin/jooq/main/keys/Keys.kt @@ -20,6 +20,7 @@ import jooq.main.tables.CourseLibrary import jooq.main.tables.CourseSpeaker import jooq.main.tables.DmLikes import jooq.main.tables.FlywaySchemaHistory +import jooq.main.tables.GithubAuth import jooq.main.tables.KotlinVersion import jooq.main.tables.Kotliner import jooq.main.tables.KotlinerLikeEntityState @@ -50,6 +51,7 @@ import jooq.main.tables.records.CourseRecord import jooq.main.tables.records.CourseSpeakerRecord import jooq.main.tables.records.DmLikesRecord import jooq.main.tables.records.FlywaySchemaHistoryRecord +import jooq.main.tables.records.GithubAuthRecord import jooq.main.tables.records.KotlinVersionRecord import jooq.main.tables.records.KotlinerLikeEntityStateRecord import jooq.main.tables.records.KotlinerReadEntityStateRecord @@ -92,6 +94,7 @@ val COURSE_LIBRARY_PKEY: UniqueKey = Internal.createUniqueK val COURSE_SPEAKER_PKEY: UniqueKey = Internal.createUniqueKey(CourseSpeaker.COURSE_SPEAKER, DSL.name("course_speaker_pkey"), arrayOf(CourseSpeaker.COURSE_SPEAKER.COURSE_ID, CourseSpeaker.COURSE_SPEAKER.KOTLINER_ID), true) val DM_LIKES_PKEY: UniqueKey = Internal.createUniqueKey(DmLikes.DM_LIKES, DSL.name("dm_likes_pkey"), arrayOf(DmLikes.DM_LIKES.ENTITY_ID), true) val FLYWAY_SCHEMA_HISTORY_PK: UniqueKey = Internal.createUniqueKey(FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY, DSL.name("flyway_schema_history_pk"), arrayOf(FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY.INSTALLED_RANK), true) +val GITHUB_AUTH_PKEY: UniqueKey = Internal.createUniqueKey(GithubAuth.GITHUB_AUTH, DSL.name("github_auth_pkey"), arrayOf(GithubAuth.GITHUB_AUTH.ID), true) val KOTLIN_VERSION_PKEY: UniqueKey = Internal.createUniqueKey(KotlinVersion.KOTLIN_VERSION, DSL.name("kotlin_version_pkey"), arrayOf(KotlinVersion.KOTLIN_VERSION.ID), true) val KOTLINER_PKEY: UniqueKey = Internal.createUniqueKey(Kotliner.KOTLINER, DSL.name("kotliner_pkey"), arrayOf(Kotliner.KOTLINER.ID), true) val UNIQUE_KOTLINER_EMAIL: UniqueKey = Internal.createUniqueKey(Kotliner.KOTLINER, DSL.name("unique_kotliner_email"), arrayOf(Kotliner.KOTLINER.NORMALIZED_EMAIL), true) diff --git a/app-backend/src/main/kotlin/jooq/main/tables/Article.kt b/app-backend/src/main/kotlin/jooq/main/tables/Article.kt index 7d8415372..b47792222 100644 --- a/app-backend/src/main/kotlin/jooq/main/tables/Article.kt +++ b/app-backend/src/main/kotlin/jooq/main/tables/Article.kt @@ -194,23 +194,7 @@ open class Article( override fun getSchema(): Schema? = if (aliased()) null else Public.PUBLIC override fun getIdentity(): Identity = super.getIdentity() as Identity override fun getPrimaryKey(): UniqueKey = ARTICLE_PKEY - override fun getReferences(): List> = listOf(ARTICLE__ARTICLE_UPDATED_BY_FKEY, ARTICLE__ARTICLE_CREATED_BY_FKEY, ARTICLE__ARTICLE_ORIGINAL_ID_FKEY) - - private lateinit var _articleUpdatedByFkey: KotlinerPath - - /** - * Get the implicit join path to the public.kotliner table, via - * the article_updated_by_fkey key. - */ - fun articleUpdatedByFkey(): KotlinerPath { - if (!this::_articleUpdatedByFkey.isInitialized) - _articleUpdatedByFkey = KotlinerPath(this, ARTICLE__ARTICLE_UPDATED_BY_FKEY, null) - - return _articleUpdatedByFkey; - } - - val articleUpdatedByFkey: KotlinerPath - get(): KotlinerPath = articleUpdatedByFkey() + override fun getReferences(): List> = listOf(ARTICLE__ARTICLE_CREATED_BY_FKEY, ARTICLE__ARTICLE_ORIGINAL_ID_FKEY, ARTICLE__ARTICLE_UPDATED_BY_FKEY) private lateinit var _articleCreatedByFkey: KotlinerPath @@ -243,6 +227,22 @@ open class Article( val article: ArticlePath get(): ArticlePath = article() + private lateinit var _articleUpdatedByFkey: KotlinerPath + + /** + * Get the implicit join path to the public.kotliner table, via + * the article_updated_by_fkey key. + */ + fun articleUpdatedByFkey(): KotlinerPath { + if (!this::_articleUpdatedByFkey.isInitialized) + _articleUpdatedByFkey = KotlinerPath(this, ARTICLE__ARTICLE_UPDATED_BY_FKEY, null) + + return _articleUpdatedByFkey; + } + + val articleUpdatedByFkey: KotlinerPath + get(): KotlinerPath = articleUpdatedByFkey() + private lateinit var _articleAuthor: ArticleAuthorPath /** diff --git a/app-backend/src/main/kotlin/jooq/main/tables/Comment.kt b/app-backend/src/main/kotlin/jooq/main/tables/Comment.kt index 6f986431f..e51dd0e43 100644 --- a/app-backend/src/main/kotlin/jooq/main/tables/Comment.kt +++ b/app-backend/src/main/kotlin/jooq/main/tables/Comment.kt @@ -147,22 +147,7 @@ open class Comment( override fun getSchema(): Schema? = if (aliased()) null else Public.PUBLIC override fun getIdentity(): Identity = super.getIdentity() as Identity override fun getPrimaryKey(): UniqueKey = COMMENT_PKEY - override fun getReferences(): List> = listOf(COMMENT__COMMENT_PARENT_ID_FKEY, COMMENT__COMMENT_KOTLINER_ID_FKEY) - - private lateinit var _comment: CommentPath - - /** - * Get the implicit join path to the public.comment table. - */ - fun comment(): CommentPath { - if (!this::_comment.isInitialized) - _comment = CommentPath(this, COMMENT__COMMENT_PARENT_ID_FKEY, null) - - return _comment; - } - - val comment: CommentPath - get(): CommentPath = comment() + override fun getReferences(): List> = listOf(COMMENT__COMMENT_KOTLINER_ID_FKEY, COMMENT__COMMENT_PARENT_ID_FKEY) private lateinit var _kotliner: KotlinerPath @@ -178,6 +163,21 @@ open class Comment( val kotliner: KotlinerPath get(): KotlinerPath = kotliner() + + private lateinit var _comment: CommentPath + + /** + * Get the implicit join path to the public.comment table. + */ + fun comment(): CommentPath { + if (!this::_comment.isInitialized) + _comment = CommentPath(this, COMMENT__COMMENT_PARENT_ID_FKEY, null) + + return _comment; + } + + val comment: CommentPath + get(): CommentPath = comment() override fun `as`(alias: String): Comment = Comment(DSL.name(alias), this) override fun `as`(alias: Name): Comment = Comment(alias, this) override fun `as`(alias: Table<*>): Comment = Comment(alias.qualifiedName, this) diff --git a/app-backend/src/main/kotlin/jooq/main/tables/GithubAuth.kt b/app-backend/src/main/kotlin/jooq/main/tables/GithubAuth.kt new file mode 100644 index 000000000..3751655b5 --- /dev/null +++ b/app-backend/src/main/kotlin/jooq/main/tables/GithubAuth.kt @@ -0,0 +1,207 @@ +/* + * This file is generated by jOOQ. + */ +package jooq.main.tables + + +import java.time.LocalDateTime +import java.util.UUID + +import jooq.main.Public +import jooq.main.keys.GITHUB_AUTH_PKEY +import jooq.main.tables.records.GithubAuthRecord + +import kotlin.collections.Collection + +import org.jooq.Condition +import org.jooq.Field +import org.jooq.ForeignKey +import org.jooq.InverseForeignKey +import org.jooq.Name +import org.jooq.PlainSQL +import org.jooq.QueryPart +import org.jooq.Record +import org.jooq.SQL +import org.jooq.Schema +import org.jooq.Select +import org.jooq.Stringly +import org.jooq.Table +import org.jooq.TableField +import org.jooq.TableOptions +import org.jooq.UniqueKey +import org.jooq.impl.DSL +import org.jooq.impl.SQLDataType +import org.jooq.impl.TableImpl + + +/** + * This class is generated by jOOQ. + */ +@Suppress("UNCHECKED_CAST") +open class GithubAuth( + alias: Name, + path: Table?, + childPath: ForeignKey?, + parentPath: InverseForeignKey?, + aliased: Table?, + parameters: Array?>?, + where: Condition? +): TableImpl( + alias, + Public.PUBLIC, + path, + childPath, + parentPath, + aliased, + parameters, + DSL.comment(""), + TableOptions.table(), + where, +) { + companion object { + + /** + * The reference instance of public.github_auth + */ + val GITHUB_AUTH: GithubAuth = GithubAuth() + } + + /** + * The class holding records for this type + */ + override fun getRecordType(): Class = GithubAuthRecord::class.java + + /** + * The column public.github_auth.id. + */ + val ID: TableField = createField(DSL.name("id"), SQLDataType.UUID.nullable(false), this, "") + + /** + * The column public.github_auth.user_id. + */ + val USER_ID: TableField = createField(DSL.name("user_id"), SQLDataType.UUID.nullable(false), this, "") + + /** + * The column public.github_auth.access_token. + */ + val ACCESS_TOKEN: TableField = createField(DSL.name("access_token"), SQLDataType.VARCHAR(1024).nullable(false), this, "") + + /** + * The column public.github_auth.expires_in. + */ + val EXPIRES_IN: TableField = createField(DSL.name("expires_in"), SQLDataType.INTEGER.nullable(false), this, "") + + /** + * The column public.github_auth.refresh_token. + */ + val REFRESH_TOKEN: TableField = createField(DSL.name("refresh_token"), SQLDataType.VARCHAR(1024).nullable(false), this, "") + + /** + * The column public.github_auth.refresh_token_expires_in. + */ + val REFRESH_TOKEN_EXPIRES_IN: TableField = createField(DSL.name("refresh_token_expires_in"), SQLDataType.INTEGER.nullable(false), this, "") + + /** + * The column public.github_auth.token_type. + */ + val TOKEN_TYPE: TableField = createField(DSL.name("token_type"), SQLDataType.VARCHAR(1024).nullable(false), this, "") + + /** + * The column public.github_auth.scope. + */ + val SCOPE: TableField = createField(DSL.name("scope"), SQLDataType.VARCHAR(1024).nullable(false), this, "") + + /** + * The column public.github_auth.created_at. + */ + val CREATED_AT: TableField = createField(DSL.name("created_at"), SQLDataType.LOCALDATETIME(6).nullable(false).defaultValue(DSL.field(DSL.raw("CURRENT_TIMESTAMP"), SQLDataType.LOCALDATETIME)), this, "") + + private constructor(alias: Name, aliased: Table?): this(alias, null, null, null, aliased, null, null) + private constructor(alias: Name, aliased: Table?, parameters: Array?>?): this(alias, null, null, null, aliased, parameters, null) + private constructor(alias: Name, aliased: Table?, where: Condition?): this(alias, null, null, null, aliased, null, where) + + /** + * Create an aliased public.github_auth table reference + */ + constructor(alias: String): this(DSL.name(alias)) + + /** + * Create an aliased public.github_auth table reference + */ + constructor(alias: Name): this(alias, null) + + /** + * Create a public.github_auth table reference + */ + constructor(): this(DSL.name("github_auth"), null) + override fun getSchema(): Schema? = if (aliased()) null else Public.PUBLIC + override fun getPrimaryKey(): UniqueKey = GITHUB_AUTH_PKEY + override fun `as`(alias: String): GithubAuth = GithubAuth(DSL.name(alias), this) + override fun `as`(alias: Name): GithubAuth = GithubAuth(alias, this) + override fun `as`(alias: Table<*>): GithubAuth = GithubAuth(alias.qualifiedName, this) + + /** + * Rename this table + */ + override fun rename(name: String): GithubAuth = GithubAuth(DSL.name(name), null) + + /** + * Rename this table + */ + override fun rename(name: Name): GithubAuth = GithubAuth(name, null) + + /** + * Rename this table + */ + override fun rename(name: Table<*>): GithubAuth = GithubAuth(name.qualifiedName, null) + + /** + * Create an inline derived table from this table + */ + override fun where(condition: Condition?): GithubAuth = GithubAuth(qualifiedName, if (aliased()) this else null, condition) + + /** + * Create an inline derived table from this table + */ + override fun where(conditions: Collection): GithubAuth = where(DSL.and(conditions)) + + /** + * Create an inline derived table from this table + */ + override fun where(vararg conditions: Condition?): GithubAuth = where(DSL.and(*conditions)) + + /** + * Create an inline derived table from this table + */ + override fun where(condition: Field?): GithubAuth = where(DSL.condition(condition)) + + /** + * Create an inline derived table from this table + */ + @PlainSQL override fun where(condition: SQL): GithubAuth = where(DSL.condition(condition)) + + /** + * Create an inline derived table from this table + */ + @PlainSQL override fun where(@Stringly.SQL condition: String): GithubAuth = where(DSL.condition(condition)) + + /** + * Create an inline derived table from this table + */ + @PlainSQL override fun where(@Stringly.SQL condition: String, vararg binds: Any?): GithubAuth = where(DSL.condition(condition, *binds)) + + /** + * Create an inline derived table from this table + */ + @PlainSQL override fun where(@Stringly.SQL condition: String, vararg parts: QueryPart): GithubAuth = where(DSL.condition(condition, *parts)) + + /** + * Create an inline derived table from this table + */ + override fun whereExists(select: Select<*>): GithubAuth = where(DSL.exists(select)) + + /** + * Create an inline derived table from this table + */ + override fun whereNotExists(select: Select<*>): GithubAuth = where(DSL.notExists(select)) +} diff --git a/app-backend/src/main/kotlin/jooq/main/tables/Kotliner.kt b/app-backend/src/main/kotlin/jooq/main/tables/Kotliner.kt index f529e77e3..1139ffd85 100644 --- a/app-backend/src/main/kotlin/jooq/main/tables/Kotliner.kt +++ b/app-backend/src/main/kotlin/jooq/main/tables/Kotliner.kt @@ -218,6 +218,22 @@ open class Kotliner( override fun getPrimaryKey(): UniqueKey = KOTLINER_PKEY override fun getUniqueKeys(): List> = listOf(UNIQUE_KOTLINER_EMAIL, UNIQUE_KOTLINER_NICKNAME) + private lateinit var _articleAuthor: ArticleAuthorPath + + /** + * Get the implicit to-many join path to the + * public.article_author table + */ + fun articleAuthor(): ArticleAuthorPath { + if (!this::_articleAuthor.isInitialized) + _articleAuthor = ArticleAuthorPath(this, null, ARTICLE_AUTHOR__ARTICLE_AUTHOR_KOTLINER_ID_FKEY.inverseKey) + + return _articleAuthor; + } + + val articleAuthor: ArticleAuthorPath + get(): ArticleAuthorPath = articleAuthor() + private lateinit var _articleCreatedByFkey: ArticlePath /** @@ -250,22 +266,6 @@ open class Kotliner( val articleUpdatedByFkey: ArticlePath get(): ArticlePath = articleUpdatedByFkey() - private lateinit var _articleAuthor: ArticleAuthorPath - - /** - * Get the implicit to-many join path to the - * public.article_author table - */ - fun articleAuthor(): ArticleAuthorPath { - if (!this::_articleAuthor.isInitialized) - _articleAuthor = ArticleAuthorPath(this, null, ARTICLE_AUTHOR__ARTICLE_AUTHOR_KOTLINER_ID_FKEY.inverseKey) - - return _articleAuthor; - } - - val articleAuthor: ArticleAuthorPath - get(): ArticleAuthorPath = articleAuthor() - private lateinit var _bookSpeaker: BookSpeakerPath /** @@ -362,22 +362,6 @@ open class Kotliner( val kugCreatedByFkey: KugPath get(): KugPath = kugCreatedByFkey() - private lateinit var _kugUpdatedByFkey: KugPath - - /** - * Get the implicit to-many join path to the public.kug table, - * via the kug_updated_by_fkey key - */ - fun kugUpdatedByFkey(): KugPath { - if (!this::_kugUpdatedByFkey.isInitialized) - _kugUpdatedByFkey = KugPath(this, null, KUG__KUG_UPDATED_BY_FKEY.inverseKey) - - return _kugUpdatedByFkey; - } - - val kugUpdatedByFkey: KugPath - get(): KugPath = kugUpdatedByFkey() - private lateinit var _kugEvent: KugEventPath /** @@ -410,6 +394,22 @@ open class Kotliner( val kugMember: KugMemberPath get(): KugMemberPath = kugMember() + private lateinit var _kugUpdatedByFkey: KugPath + + /** + * Get the implicit to-many join path to the public.kug table, + * via the kug_updated_by_fkey key + */ + fun kugUpdatedByFkey(): KugPath { + if (!this::_kugUpdatedByFkey.isInitialized) + _kugUpdatedByFkey = KugPath(this, null, KUG__KUG_UPDATED_BY_FKEY.inverseKey) + + return _kugUpdatedByFkey; + } + + val kugUpdatedByFkey: KugPath + get(): KugPath = kugUpdatedByFkey() + private lateinit var _vacancy: VacancyPath /** diff --git a/app-backend/src/main/kotlin/jooq/main/tables/KugEvent.kt b/app-backend/src/main/kotlin/jooq/main/tables/KugEvent.kt index e5e2bc351..d99330c35 100644 --- a/app-backend/src/main/kotlin/jooq/main/tables/KugEvent.kt +++ b/app-backend/src/main/kotlin/jooq/main/tables/KugEvent.kt @@ -163,22 +163,7 @@ open class KugEvent( override fun getSchema(): Schema? = if (aliased()) null else Public.PUBLIC override fun getIdentity(): Identity = super.getIdentity() as Identity override fun getPrimaryKey(): UniqueKey = KUG_EVENT_PKEY - override fun getReferences(): List> = listOf(KUG_EVENT__KUG_EVENT_UPDATED_BY_FKEY, KUG_EVENT__KUG_EVENT_KUG_ID_FKEY) - - private lateinit var _kotliner: KotlinerPath - - /** - * Get the implicit join path to the public.kotliner table. - */ - fun kotliner(): KotlinerPath { - if (!this::_kotliner.isInitialized) - _kotliner = KotlinerPath(this, KUG_EVENT__KUG_EVENT_UPDATED_BY_FKEY, null) - - return _kotliner; - } - - val kotliner: KotlinerPath - get(): KotlinerPath = kotliner() + override fun getReferences(): List> = listOf(KUG_EVENT__KUG_EVENT_KUG_ID_FKEY, KUG_EVENT__KUG_EVENT_UPDATED_BY_FKEY) private lateinit var _kug: KugPath @@ -194,6 +179,21 @@ open class KugEvent( val kug: KugPath get(): KugPath = kug() + + private lateinit var _kotliner: KotlinerPath + + /** + * Get the implicit join path to the public.kotliner table. + */ + fun kotliner(): KotlinerPath { + if (!this::_kotliner.isInitialized) + _kotliner = KotlinerPath(this, KUG_EVENT__KUG_EVENT_UPDATED_BY_FKEY, null) + + return _kotliner; + } + + val kotliner: KotlinerPath + get(): KotlinerPath = kotliner() override fun `as`(alias: String): KugEvent = KugEvent(DSL.name(alias), this) override fun `as`(alias: Name): KugEvent = KugEvent(alias, this) override fun `as`(alias: Table<*>): KugEvent = KugEvent(alias.qualifiedName, this) diff --git a/app-backend/src/main/kotlin/jooq/main/tables/VideoLibrary.kt b/app-backend/src/main/kotlin/jooq/main/tables/VideoLibrary.kt index cd6a6d23b..0a96f43f4 100644 --- a/app-backend/src/main/kotlin/jooq/main/tables/VideoLibrary.kt +++ b/app-backend/src/main/kotlin/jooq/main/tables/VideoLibrary.kt @@ -118,22 +118,7 @@ open class VideoLibrary( } override fun getSchema(): Schema? = if (aliased()) null else Public.PUBLIC override fun getPrimaryKey(): UniqueKey = VIDEO_LIBRARY_PKEY - override fun getReferences(): List> = listOf(VIDEO_LIBRARY__VIDEO_LIBRARY_VIDEO_ID_FKEY, VIDEO_LIBRARY__VIDEO_LIBRARY_LIBRARY_ID_FKEY) - - private lateinit var _video: VideoPath - - /** - * Get the implicit join path to the public.video table. - */ - fun video(): VideoPath { - if (!this::_video.isInitialized) - _video = VideoPath(this, VIDEO_LIBRARY__VIDEO_LIBRARY_VIDEO_ID_FKEY, null) - - return _video; - } - - val video: VideoPath - get(): VideoPath = video() + override fun getReferences(): List> = listOf(VIDEO_LIBRARY__VIDEO_LIBRARY_LIBRARY_ID_FKEY, VIDEO_LIBRARY__VIDEO_LIBRARY_VIDEO_ID_FKEY) private lateinit var _library: LibraryPath @@ -149,6 +134,21 @@ open class VideoLibrary( val library: LibraryPath get(): LibraryPath = library() + + private lateinit var _video: VideoPath + + /** + * Get the implicit join path to the public.video table. + */ + fun video(): VideoPath { + if (!this::_video.isInitialized) + _video = VideoPath(this, VIDEO_LIBRARY__VIDEO_LIBRARY_VIDEO_ID_FKEY, null) + + return _video; + } + + val video: VideoPath + get(): VideoPath = video() override fun `as`(alias: String): VideoLibrary = VideoLibrary(DSL.name(alias), this) override fun `as`(alias: Name): VideoLibrary = VideoLibrary(alias, this) override fun `as`(alias: Table<*>): VideoLibrary = VideoLibrary(alias.qualifiedName, this) diff --git a/app-backend/src/main/kotlin/jooq/main/tables/VideoSpeaker.kt b/app-backend/src/main/kotlin/jooq/main/tables/VideoSpeaker.kt index 835a8075e..b7589fbe2 100644 --- a/app-backend/src/main/kotlin/jooq/main/tables/VideoSpeaker.kt +++ b/app-backend/src/main/kotlin/jooq/main/tables/VideoSpeaker.kt @@ -118,22 +118,7 @@ open class VideoSpeaker( } override fun getSchema(): Schema? = if (aliased()) null else Public.PUBLIC override fun getPrimaryKey(): UniqueKey = VIDEO_SPEAKER_PKEY - override fun getReferences(): List> = listOf(VIDEO_SPEAKER__VIDEO_SPEAKER_VIDEO_ID_FKEY, VIDEO_SPEAKER__VIDEO_SPEAKER_KOTLINER_ID_FKEY) - - private lateinit var _video: VideoPath - - /** - * Get the implicit join path to the public.video table. - */ - fun video(): VideoPath { - if (!this::_video.isInitialized) - _video = VideoPath(this, VIDEO_SPEAKER__VIDEO_SPEAKER_VIDEO_ID_FKEY, null) - - return _video; - } - - val video: VideoPath - get(): VideoPath = video() + override fun getReferences(): List> = listOf(VIDEO_SPEAKER__VIDEO_SPEAKER_KOTLINER_ID_FKEY, VIDEO_SPEAKER__VIDEO_SPEAKER_VIDEO_ID_FKEY) private lateinit var _kotliner: KotlinerPath @@ -149,6 +134,21 @@ open class VideoSpeaker( val kotliner: KotlinerPath get(): KotlinerPath = kotliner() + + private lateinit var _video: VideoPath + + /** + * Get the implicit join path to the public.video table. + */ + fun video(): VideoPath { + if (!this::_video.isInitialized) + _video = VideoPath(this, VIDEO_SPEAKER__VIDEO_SPEAKER_VIDEO_ID_FKEY, null) + + return _video; + } + + val video: VideoPath + get(): VideoPath = video() override fun `as`(alias: String): VideoSpeaker = VideoSpeaker(DSL.name(alias), this) override fun `as`(alias: Name): VideoSpeaker = VideoSpeaker(alias, this) override fun `as`(alias: Table<*>): VideoSpeaker = VideoSpeaker(alias.qualifiedName, this) diff --git a/app-backend/src/main/kotlin/jooq/main/tables/daos/GithubAuthDao.kt b/app-backend/src/main/kotlin/jooq/main/tables/daos/GithubAuthDao.kt new file mode 100644 index 000000000..a3efa57f4 --- /dev/null +++ b/app-backend/src/main/kotlin/jooq/main/tables/daos/GithubAuthDao.kt @@ -0,0 +1,135 @@ +/* + * This file is generated by jOOQ. + */ +package jooq.main.tables.daos + + +import java.time.LocalDateTime +import java.util.UUID + +import jooq.main.tables.GithubAuth +import jooq.main.tables.records.GithubAuthRecord + +import kotlin.collections.List + +import org.jooq.Configuration +import org.jooq.impl.DAOImpl + + +/** + * This class is generated by jOOQ. + */ +@Suppress("UNCHECKED_CAST") +open class GithubAuthDao(configuration: Configuration?) : DAOImpl(GithubAuth.GITHUB_AUTH, jooq.main.tables.pojos.GithubAuth::class.java, configuration) { + + /** + * Create a new GithubAuthDao without any configuration + */ + constructor(): this(null) + + override fun getId(o: jooq.main.tables.pojos.GithubAuth): UUID? = o.id + + /** + * Fetch records that have id BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfId(lowerInclusive: UUID?, upperInclusive: UUID?): List = fetchRange(GithubAuth.GITHUB_AUTH.ID, lowerInclusive, upperInclusive) + + /** + * Fetch records that have id IN (values) + */ + fun fetchById(vararg values: UUID): List = fetch(GithubAuth.GITHUB_AUTH.ID, *values) + + /** + * Fetch a unique record that has id = value + */ + fun fetchOneById(value: UUID): jooq.main.tables.pojos.GithubAuth? = fetchOne(GithubAuth.GITHUB_AUTH.ID, value) + + /** + * Fetch records that have user_id BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfUserId(lowerInclusive: UUID?, upperInclusive: UUID?): List = fetchRange(GithubAuth.GITHUB_AUTH.USER_ID, lowerInclusive, upperInclusive) + + /** + * Fetch records that have user_id IN (values) + */ + fun fetchByUserId(vararg values: UUID): List = fetch(GithubAuth.GITHUB_AUTH.USER_ID, *values) + + /** + * Fetch records that have access_token BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfAccessToken(lowerInclusive: String?, upperInclusive: String?): List = fetchRange(GithubAuth.GITHUB_AUTH.ACCESS_TOKEN, lowerInclusive, upperInclusive) + + /** + * Fetch records that have access_token IN (values) + */ + fun fetchByAccessToken(vararg values: String): List = fetch(GithubAuth.GITHUB_AUTH.ACCESS_TOKEN, *values) + + /** + * Fetch records that have expires_in BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfExpiresIn(lowerInclusive: Int?, upperInclusive: Int?): List = fetchRange(GithubAuth.GITHUB_AUTH.EXPIRES_IN, lowerInclusive, upperInclusive) + + /** + * Fetch records that have expires_in IN (values) + */ + fun fetchByExpiresIn(vararg values: Int): List = fetch(GithubAuth.GITHUB_AUTH.EXPIRES_IN, *values.toTypedArray()) + + /** + * Fetch records that have refresh_token BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfRefreshToken(lowerInclusive: String?, upperInclusive: String?): List = fetchRange(GithubAuth.GITHUB_AUTH.REFRESH_TOKEN, lowerInclusive, upperInclusive) + + /** + * Fetch records that have refresh_token IN (values) + */ + fun fetchByRefreshToken(vararg values: String): List = fetch(GithubAuth.GITHUB_AUTH.REFRESH_TOKEN, *values) + + /** + * Fetch records that have refresh_token_expires_in BETWEEN + * lowerInclusive AND upperInclusive + */ + fun fetchRangeOfRefreshTokenExpiresIn(lowerInclusive: Int?, upperInclusive: Int?): List = fetchRange(GithubAuth.GITHUB_AUTH.REFRESH_TOKEN_EXPIRES_IN, lowerInclusive, upperInclusive) + + /** + * Fetch records that have refresh_token_expires_in IN (values) + */ + fun fetchByRefreshTokenExpiresIn(vararg values: Int): List = fetch(GithubAuth.GITHUB_AUTH.REFRESH_TOKEN_EXPIRES_IN, *values.toTypedArray()) + + /** + * Fetch records that have token_type BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfTokenType(lowerInclusive: String?, upperInclusive: String?): List = fetchRange(GithubAuth.GITHUB_AUTH.TOKEN_TYPE, lowerInclusive, upperInclusive) + + /** + * Fetch records that have token_type IN (values) + */ + fun fetchByTokenType(vararg values: String): List = fetch(GithubAuth.GITHUB_AUTH.TOKEN_TYPE, *values) + + /** + * Fetch records that have scope BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfScope(lowerInclusive: String?, upperInclusive: String?): List = fetchRange(GithubAuth.GITHUB_AUTH.SCOPE, lowerInclusive, upperInclusive) + + /** + * Fetch records that have scope IN (values) + */ + fun fetchByScope(vararg values: String): List = fetch(GithubAuth.GITHUB_AUTH.SCOPE, *values) + + /** + * Fetch records that have created_at BETWEEN lowerInclusive AND + * upperInclusive + */ + fun fetchRangeOfCreatedAt(lowerInclusive: LocalDateTime?, upperInclusive: LocalDateTime?): List = fetchRange(GithubAuth.GITHUB_AUTH.CREATED_AT, lowerInclusive, upperInclusive) + + /** + * Fetch records that have created_at IN (values) + */ + fun fetchByCreatedAt(vararg values: LocalDateTime): List = fetch(GithubAuth.GITHUB_AUTH.CREATED_AT, *values) +} diff --git a/app-backend/src/main/kotlin/jooq/main/tables/pojos/GithubAuth.kt b/app-backend/src/main/kotlin/jooq/main/tables/pojos/GithubAuth.kt new file mode 100644 index 000000000..f9508e188 --- /dev/null +++ b/app-backend/src/main/kotlin/jooq/main/tables/pojos/GithubAuth.kt @@ -0,0 +1,125 @@ +/* + * This file is generated by jOOQ. + */ +package jooq.main.tables.pojos + + +import java.io.Serializable +import java.time.LocalDateTime +import java.util.UUID + + +/** + * This class is generated by jOOQ. + */ +@Suppress("UNCHECKED_CAST") +data class GithubAuth( + var id: UUID? = null, + var userId: UUID? = null, + var accessToken: String? = null, + var expiresIn: Int? = null, + var refreshToken: String? = null, + var refreshTokenExpiresIn: Int? = null, + var tokenType: String? = null, + var scope: String? = null, + var createdAt: LocalDateTime? = null +): Serializable { + + + override fun equals(other: Any?): Boolean { + if (this === other) + return true + if (other == null) + return false + if (this::class != other::class) + return false + val o: GithubAuth = other as GithubAuth + if (this.id == null) { + if (o.id != null) + return false + } + else if (this.id != o.id) + return false + if (this.userId == null) { + if (o.userId != null) + return false + } + else if (this.userId != o.userId) + return false + if (this.accessToken == null) { + if (o.accessToken != null) + return false + } + else if (this.accessToken != o.accessToken) + return false + if (this.expiresIn == null) { + if (o.expiresIn != null) + return false + } + else if (this.expiresIn != o.expiresIn) + return false + if (this.refreshToken == null) { + if (o.refreshToken != null) + return false + } + else if (this.refreshToken != o.refreshToken) + return false + if (this.refreshTokenExpiresIn == null) { + if (o.refreshTokenExpiresIn != null) + return false + } + else if (this.refreshTokenExpiresIn != o.refreshTokenExpiresIn) + return false + if (this.tokenType == null) { + if (o.tokenType != null) + return false + } + else if (this.tokenType != o.tokenType) + return false + if (this.scope == null) { + if (o.scope != null) + return false + } + else if (this.scope != o.scope) + return false + if (this.createdAt == null) { + if (o.createdAt != null) + return false + } + else if (this.createdAt != o.createdAt) + return false + return true + } + + override fun hashCode(): Int { + val prime = 31 + var result = 1 + result = prime * result + (if (this.id == null) 0 else this.id.hashCode()) + result = prime * result + (if (this.userId == null) 0 else this.userId.hashCode()) + result = prime * result + (if (this.accessToken == null) 0 else this.accessToken.hashCode()) + result = prime * result + (if (this.expiresIn == null) 0 else this.expiresIn.hashCode()) + result = prime * result + (if (this.refreshToken == null) 0 else this.refreshToken.hashCode()) + result = prime * result + (if (this.refreshTokenExpiresIn == null) 0 else this.refreshTokenExpiresIn.hashCode()) + result = prime * result + (if (this.tokenType == null) 0 else this.tokenType.hashCode()) + result = prime * result + (if (this.scope == null) 0 else this.scope.hashCode()) + result = prime * result + (if (this.createdAt == null) 0 else this.createdAt.hashCode()) + return result + } + + override fun toString(): String { + val sb = StringBuilder("GithubAuth (") + + sb.append(id) + sb.append(", ").append(userId) + sb.append(", ").append(accessToken) + sb.append(", ").append(expiresIn) + sb.append(", ").append(refreshToken) + sb.append(", ").append(refreshTokenExpiresIn) + sb.append(", ").append(tokenType) + sb.append(", ").append(scope) + sb.append(", ").append(createdAt) + + sb.append(")") + return sb.toString() + } +} diff --git a/app-backend/src/main/kotlin/jooq/main/tables/records/GithubAuthRecord.kt b/app-backend/src/main/kotlin/jooq/main/tables/records/GithubAuthRecord.kt new file mode 100644 index 000000000..4e4538890 --- /dev/null +++ b/app-backend/src/main/kotlin/jooq/main/tables/records/GithubAuthRecord.kt @@ -0,0 +1,97 @@ +/* + * This file is generated by jOOQ. + */ +package jooq.main.tables.records + + +import java.time.LocalDateTime +import java.util.UUID + +import jooq.main.tables.GithubAuth + +import org.jooq.Record1 +import org.jooq.impl.UpdatableRecordImpl + + +/** + * This class is generated by jOOQ. + */ +@Suppress("UNCHECKED_CAST") +open class GithubAuthRecord() : UpdatableRecordImpl(GithubAuth.GITHUB_AUTH) { + + open var id: UUID? + set(value): Unit = set(0, value) + get(): UUID? = get(0) as UUID? + + open var userId: UUID? + set(value): Unit = set(1, value) + get(): UUID? = get(1) as UUID? + + open var accessToken: String? + set(value): Unit = set(2, value) + get(): String? = get(2) as String? + + open var expiresIn: Int? + set(value): Unit = set(3, value) + get(): Int? = get(3) as Int? + + open var refreshToken: String? + set(value): Unit = set(4, value) + get(): String? = get(4) as String? + + open var refreshTokenExpiresIn: Int? + set(value): Unit = set(5, value) + get(): Int? = get(5) as Int? + + open var tokenType: String? + set(value): Unit = set(6, value) + get(): String? = get(6) as String? + + open var scope: String? + set(value): Unit = set(7, value) + get(): String? = get(7) as String? + + open var createdAt: LocalDateTime? + set(value): Unit = set(8, value) + get(): LocalDateTime? = get(8) as LocalDateTime? + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + override fun key(): Record1 = super.key() as Record1 + + /** + * Create a detached, initialised GithubAuthRecord + */ + constructor(id: UUID? = null, userId: UUID? = null, accessToken: String? = null, expiresIn: Int? = null, refreshToken: String? = null, refreshTokenExpiresIn: Int? = null, tokenType: String? = null, scope: String? = null, createdAt: LocalDateTime? = null): this() { + this.id = id + this.userId = userId + this.accessToken = accessToken + this.expiresIn = expiresIn + this.refreshToken = refreshToken + this.refreshTokenExpiresIn = refreshTokenExpiresIn + this.tokenType = tokenType + this.scope = scope + this.createdAt = createdAt + resetChangedOnNotNull() + } + + /** + * Create a detached, initialised GithubAuthRecord + */ + constructor(value: jooq.main.tables.pojos.GithubAuth?): this() { + if (value != null) { + this.id = value.id + this.userId = value.userId + this.accessToken = value.accessToken + this.expiresIn = value.expiresIn + this.refreshToken = value.refreshToken + this.refreshTokenExpiresIn = value.refreshTokenExpiresIn + this.tokenType = value.tokenType + this.scope = value.scope + this.createdAt = value.createdAt + resetChangedOnNotNull() + } + } +} diff --git a/app-backend/src/main/kotlin/jooq/main/tables/references/Tables.kt b/app-backend/src/main/kotlin/jooq/main/tables/references/Tables.kt index ea7d370ab..88a7a140d 100644 --- a/app-backend/src/main/kotlin/jooq/main/tables/references/Tables.kt +++ b/app-backend/src/main/kotlin/jooq/main/tables/references/Tables.kt @@ -21,6 +21,7 @@ import jooq.main.tables.CourseSpeaker import jooq.main.tables.DmLikes import jooq.main.tables.EntityTopic import jooq.main.tables.FlywaySchemaHistory +import jooq.main.tables.GithubAuth import jooq.main.tables.KotlinVersion import jooq.main.tables.Kotliner import jooq.main.tables.KotlinerLikeEntityState @@ -124,6 +125,11 @@ val ENTITY_TOPIC: EntityTopic = EntityTopic.ENTITY_TOPIC */ val FLYWAY_SCHEMA_HISTORY: FlywaySchemaHistory = FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY +/** + * The table public.github_auth. + */ +val GITHUB_AUTH: GithubAuth = GithubAuth.GITHUB_AUTH + /** * The table public.kotlin_version. */ diff --git a/app-backend/src/main/kotlin/ktor/KtorRoute.kt b/app-backend/src/main/kotlin/ktor/KtorRoute.kt deleted file mode 100644 index 98f69bf1e..000000000 --- a/app-backend/src/main/kotlin/ktor/KtorRoute.kt +++ /dev/null @@ -1,7 +0,0 @@ -package ktor - -import io.ktor.server.routing.* - -interface KtorRoute { - fun Routing.install() -} diff --git a/app-backend/src/main/kotlin/ktor/plugins/HTTP.kt b/app-backend/src/main/kotlin/ktor/plugins/HTTP.kt deleted file mode 100644 index 441df6822..000000000 --- a/app-backend/src/main/kotlin/ktor/plugins/HTTP.kt +++ /dev/null @@ -1,112 +0,0 @@ -package ktor.plugins - -import com.auth0.jwt.JWT -import com.auth0.jwt.algorithms.Algorithm - -import io.ktor.http.CacheControl -import io.ktor.http.ContentType -import io.ktor.http.HttpStatusCode -import io.ktor.http.auth.* -import io.ktor.http.content.CachingOptions -import io.ktor.serialization.kotlinx.json.json -import io.ktor.server.application.Application -import io.ktor.server.application.install -import io.ktor.server.auth.authentication -import io.ktor.server.auth.jwt.JWTPrincipal -import io.ktor.server.auth.jwt.jwt -import io.ktor.server.plugins.cachingheaders.CachingHeaders -import io.ktor.server.plugins.contentnegotiation.ContentNegotiation -import io.ktor.server.plugins.defaultheaders.DefaultHeaders -import io.ktor.server.plugins.statuspages.StatusPages -import io.ktor.server.resources.Resources -import io.ktor.server.response.respond -import kotlinx.serialization.Serializable -import usecases.signup.JwtModule -import utils.logger -import kotlin.time.Duration.Companion.days - -fun Application.defaults( - jwtConfig: JwtModule.JwtConfig, -) { - install(Resources) - - install(ContentNegotiation) { - json() - } - - install(DefaultHeaders) { - header("X-Application", "awesome-kotlin/v2") - } - - install(CachingHeaders) { - options { _, outgoingContent -> - when (outgoingContent.contentType?.withoutParameters()) { - ContentType.Text.CSS -> CachingOptions( - CacheControl.MaxAge( - maxAgeSeconds = 365.days - .inWholeSeconds - .toInt() - ) - ) - else -> null - } - } - } - - install(StatusPages) { - exception { call, _ -> - call.respond(HttpStatusCode.Unauthorized) - } - exception { call, _ -> - call.respond(HttpStatusCode.Forbidden) - } - exception { call, cause -> - call.respond(HttpStatusCode.BadRequest, cause.fields) - } - } - - authentication { - jwt("jwt") { - realm = jwtConfig.realm - authHeader { call -> - try { - call.request.cookies["token"] - ?.let { cookieValue -> - parseAuthorizationHeader("Bearer $cookieValue") - } - } catch (cause: IllegalArgumentException) { - logger {}.info("Failed to parse JWT from cookie", cause) - null - } - } - verifier( - JWT - .require(Algorithm.HMAC512(jwtConfig.secret)) - .withAudience(jwtConfig.audience) - .withIssuer(jwtConfig.issuer) - .build() - ) - validate { credential -> - if (credential.payload.audience.contains(jwtConfig.audience)) { - JWTPrincipal(credential.payload) - } else { - null - } - } - } - } -} - -class AuthenticationException : RuntimeException() - -class AuthorizationException : RuntimeException() - -class ConstraintViolationException( - val fields: List, -) : RuntimeException() - -@Serializable -data class ConstraintViolationFields( - val message: String, - val fields: List, -) diff --git a/app-backend/src/main/kotlin/ktor/plugins/Monitoring.kt b/app-backend/src/main/kotlin/ktor/plugins/Monitoring.kt deleted file mode 100644 index 2d05fa1dc..000000000 --- a/app-backend/src/main/kotlin/ktor/plugins/Monitoring.kt +++ /dev/null @@ -1,31 +0,0 @@ -package ktor.plugins - -import io.ktor.server.application.Application -import io.ktor.server.application.install -import io.ktor.server.metrics.micrometer.MicrometerMetrics -import io.ktor.server.plugins.calllogging.CallLogging -import io.ktor.server.request.path -import io.ktor.server.response.respond -import io.ktor.server.routing.get -import io.ktor.server.routing.routing -import io.micrometer.prometheusmetrics.PrometheusMeterRegistry -import org.slf4j.event.Level - -fun Application.configureMonitoring( - meterRegistry: PrometheusMeterRegistry, -) { - install(MicrometerMetrics) { - registry = meterRegistry - } - - install(CallLogging) { - level = Level.INFO - filter { call -> call.request.path().startsWith("/") } - } - - routing { - get("/metrics-micrometer") { - call.respond(meterRegistry.scrape()) - } - } -} diff --git a/app-backend/src/main/kotlin/ktor/plugins/Sockets.kt b/app-backend/src/main/kotlin/ktor/plugins/Sockets.kt deleted file mode 100644 index c782185e3..000000000 --- a/app-backend/src/main/kotlin/ktor/plugins/Sockets.kt +++ /dev/null @@ -1,39 +0,0 @@ -package ktor.plugins - -import io.ktor.websocket.* -import io.ktor.server.application.Application -import io.ktor.server.application.install -import io.ktor.server.routing.routing -import io.ktor.server.websocket.WebSockets -import io.ktor.server.websocket.pingPeriod -import io.ktor.server.websocket.timeout -import io.ktor.server.websocket.webSocket -import kotlin.time.Duration.Companion.seconds - -fun Application.configureSockets() { - install(WebSockets) { - pingPeriod = 15.seconds - timeout = 15.seconds - maxFrameSize = Long.MAX_VALUE - masking = false - } - - routing { - webSocket("/ws") { - println("new session is open") - for (frame in incoming) { - frame.fin - when (frame) { - is Frame.Text -> { - val text = frame.readText() - outgoing.send(Frame.Text("YOU SAID: $text")) - if (text.equals("bye", ignoreCase = true)) { - close(CloseReason(CloseReason.Codes.NORMAL, "Client said BYE")) - } - } - else -> {} - } - } - } - } -} diff --git a/app-backend/src/main/kotlin/model/KotlinPlatform.kt b/app-backend/src/main/kotlin/model/KotlinPlatform.kt deleted file mode 100644 index c9e985d72..000000000 --- a/app-backend/src/main/kotlin/model/KotlinPlatform.kt +++ /dev/null @@ -1,32 +0,0 @@ -package model - -enum class KotlinPlatform { - /** - * Kotlin/Native target. - * For iOS specif libraries, please use [IOS]. - */ - Native, - /** - * Libraries and Projects that dependent on Android APIs. - * For libraries that supposed to used in Android apps, - * but doesn't depend on Android, please use [JVM]. - */ - Android, - /** - * Libraries and Projects that dependent on iOS APIs. - */ - IOS, - /** - * Generic JVM libraries and projects. - */ - JVM, - /** - * Libraries for Kotlin/JS, both frontend and backend. - */ - JS, - /** - * Multi-Platform projects. Please, also define supported targets, like: - * [JVM], [JS] - */ - MPP -} diff --git a/app-backend/src/main/kotlin/model/KotlinVersion.kt b/app-backend/src/main/kotlin/model/KotlinVersion.kt deleted file mode 100644 index b995c3eea..000000000 --- a/app-backend/src/main/kotlin/model/KotlinVersion.kt +++ /dev/null @@ -1,3 +0,0 @@ -package model - -data class KotlinVersion(val value: String) diff --git a/app-backend/src/main/kotlin/model/Language.kt b/app-backend/src/main/kotlin/model/Language.kt deleted file mode 100644 index b9b5e83e5..000000000 --- a/app-backend/src/main/kotlin/model/Language.kt +++ /dev/null @@ -1,6 +0,0 @@ -package model - -data class Language( - val code: String, - val url: String -) diff --git a/app-backend/src/main/kotlin/server/KtorRoutesModule.kt b/app-backend/src/main/kotlin/server/KtorRoutesModule.kt new file mode 100644 index 000000000..fd74d0979 --- /dev/null +++ b/app-backend/src/main/kotlin/server/KtorRoutesModule.kt @@ -0,0 +1,64 @@ +package server + +import infra.metrics.MetricsModule +import io.heapy.komok.tech.di.lib.Module +import usecases.articles.ArticlesModule +import usecases.github.GithubModule +import usecases.healthcheck.HealthcheckModule +import usecases.kug.KugModule +import usecases.links.LinksModule +import usecases.readme.ReadmeModule +import usecases.robots_txt.RobotsTxtModule +import usecases.rss.RssModule +import usecases.signup.LoginModule +import usecases.signup.RegisterModule +import usecases.sitemap.SitemapModule +import usecases.version.KotlinVersionModule + +@Module +open class KtorRoutesModule( + private val githubModule: GithubModule, + private val healthcheckModule: HealthcheckModule, + private val loginModule: LoginModule, + private val registerModule: RegisterModule, + private val linksModule: LinksModule, + private val kugModule: KugModule, + private val metricsModule: MetricsModule, + private val rssModule: RssModule, + private val kotlinVersionModule: KotlinVersionModule, + private val robotsTxtModule: RobotsTxtModule, + private val sitemapModule: SitemapModule, + private val readmeModule: ReadmeModule, + private val articlesModule: ArticlesModule, +) { + open val unauthenticatedRoutes by lazy { + listOf( + githubModule.githubRedirectRoute, + githubModule.githubCallbackRoute, + + healthcheckModule.route, + + metricsModule.route, + + loginModule.route, + registerModule.route, + + linksModule.route, + kugModule.updateKugsRoute, + + rssModule.rssRoute, + rssModule.fullRssRoute, + + kotlinVersionModule.route, + + robotsTxtModule.route, + + sitemapModule.route, + + readmeModule.route, + + articlesModule.pagesRoute, + articlesModule.pagesIndexRoute, + ) + } +} diff --git a/app-backend/src/main/kotlin/server/KtorServerModule.kt b/app-backend/src/main/kotlin/server/KtorServerModule.kt new file mode 100644 index 000000000..5587c74c1 --- /dev/null +++ b/app-backend/src/main/kotlin/server/KtorServerModule.kt @@ -0,0 +1,85 @@ +package server + +import infra.config.ConfigModule +import infra.config.decode +import io.heapy.komok.tech.di.lib.Module +import io.ktor.server.auth.* +import io.ktor.server.auth.jwt.* +import io.ktor.server.cio.* +import io.ktor.server.engine.* +import io.ktor.server.http.content.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import kotlinx.serialization.Serializable +import infra.ktor.KtorFeaturesModule +import infra.lifecycle.LifecycleModule +import infra.utils.withEach +import java.io.File +import kotlin.time.Duration + +@Module +open class KtorServerModule( + private val lifecycleModule: LifecycleModule, + private val configModule: ConfigModule, + private val ktorFeaturesModule: KtorFeaturesModule, + private val ktorRoutesModule: KtorRoutesModule, +) { + open val ktorServer by lazy { + System.setProperty("io.ktor.server.engine.ShutdownHook", "false") + + val features = ktorFeaturesModule.features + val unauthenticatedRoutes = ktorRoutesModule.unauthenticatedRoutes + val serverConfig = serverConfig + + embeddedServer( + factory = CIO, + port = serverConfig.port, + host = serverConfig.host, + ) { + features.withEach { + install() + } + + routing { + staticFiles("/", File(serverConfig.reactDistPath)) { + default("index.html") + } + + unauthenticatedRoutes.withEach { + install() + } + + authenticate("jwt") { + get("/test") { + val principal = call.principal() + principal?.getClaim("id", Long::class)?.let { id -> + call.respond("Hello, $id!") + } ?: call.respond("Hello, world!") + } + } + } + }.also { server -> + lifecycleModule.shutdownHandler.addHandler { + server.stop( + gracePeriodMillis = serverConfig.gracefulShutdownTimeout.inWholeMilliseconds, + timeoutMillis = 5000, + ) + } + } + } + + open val serverConfig: ServerConfig by lazy { + configModule.decode( + "server", + deserializer = ServerConfig.serializer(), + ) + } + + @Serializable + data class ServerConfig( + val port: Int, + val host: String, + val gracefulShutdownTimeout: Duration, + val reactDistPath: String, + ) +} diff --git a/app-backend/src/main/kotlin/usecases/articles/ArticleSource.kt b/app-backend/src/main/kotlin/usecases/articles/ArticleSource.kt new file mode 100644 index 000000000..68b428d24 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/articles/ArticleSource.kt @@ -0,0 +1,79 @@ +package usecases.articles + +import infra.serialization.LocalDateTimeSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.json.Json +import java.time.LocalDate + +class ArticleSource( + private val articlesProcessor: ArticlesProcessor, +) { + fun getArticles(): List
{ + val json = ArticleSource::class.java + .classLoader + .getResource("data/articles.json") + .readText() + + return Json + .decodeFromString(ListSerializer(Article.serializer()), json) + .map(articlesProcessor::process) + } +} + +enum class ArticleFeature { + mathjax, + highlightjs +} + +enum class LinkType { + article, + video, + slides, + webinar +} + +@Serializable +data class Article( + val title: String, + val url: String, + val body: String, + val author: String, + @Serializable(with = LocalDateTimeSerializer::class) + val date: LocalDate, + val type: LinkType, + val categories: List = listOf(), + val features: List = listOf(ArticleFeature.highlightjs), + val description: String = "", + val filename: String = "", + val lang: LanguageCodes = LanguageCodes.EN, + val enclosure: Enclosure? = null +) + +@Serializable +data class Enclosure( + val url: String, + val size: Int +) + +/** + * List of languages names - codes according ISO 639-1 + * https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes + * + * @author Ibragimov Ruslan + * @since 0.1 + */ +enum class LanguageCodes(val id: String) { + EN("english"), + RU("russian"), + IT("italian"), + ZH("chinese"), + HE("hebrew"); + + companion object { + fun contains(language: String) = + entries + .map(LanguageCodes::id) + .contains(language) + } +} diff --git a/app-backend/src/main/kotlin/usecases/articles/ArticlesModule.kt b/app-backend/src/main/kotlin/usecases/articles/ArticlesModule.kt new file mode 100644 index 000000000..56cd27774 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/articles/ArticlesModule.kt @@ -0,0 +1,50 @@ +package usecases.articles + +import io.heapy.komok.tech.di.lib.Module +import org.commonmark.ext.gfm.tables.TablesExtension +import org.commonmark.parser.Parser +import org.commonmark.renderer.html.HtmlRenderer + +@Module +open class ArticlesModule { + open val articleSource by lazy { + ArticleSource( + articlesProcessor = articlesProcessor, + ) + } + + open val markdownRenderer by lazy { + val extensions = listOf(TablesExtension.create()) + val parser = Parser.builder().extensions(extensions).build() + val renderer = HtmlRenderer.builder().extensions(extensions).build() + + MarkdownRenderer( + parser = parser, + renderer = renderer + ) + } + + open val articlesProcessor by lazy { + ArticlesProcessor( + markdownRenderer = markdownRenderer, + ) + } + + open val pagesGenerator by lazy { + PagesGenerator() + } + + open val pagesIndexRoute by lazy { + PagesIndexRoute( + articlesSource = articleSource, + pagesGenerator = pagesGenerator, + ) + } + + open val pagesRoute by lazy { + PagesRoute( + articlesSource = articleSource, + pagesGenerator = pagesGenerator, + ) + } +} diff --git a/src/main/kotlin/link/kotlin/scripts/ArticlesProcessor.kt b/app-backend/src/main/kotlin/usecases/articles/ArticlesProcessor.kt similarity index 79% rename from src/main/kotlin/link/kotlin/scripts/ArticlesProcessor.kt rename to app-backend/src/main/kotlin/usecases/articles/ArticlesProcessor.kt index 834654ba8..e90b4d3a6 100644 --- a/src/main/kotlin/link/kotlin/scripts/ArticlesProcessor.kt +++ b/app-backend/src/main/kotlin/usecases/articles/ArticlesProcessor.kt @@ -1,17 +1,9 @@ -package link.kotlin.scripts +package usecases.articles -import link.kotlin.scripts.dsl.Article - -interface ArticlesProcessor { - fun process(article: Article): Article - - companion object -} - -private class DefaultArticlesProcessor( - private val markdownRenderer: MarkdownRenderer -) : ArticlesProcessor { - override fun process(article: Article): Article { +class ArticlesProcessor( + private val markdownRenderer: MarkdownRenderer, +) { + fun process(article: Article): Article { val html = markdownRenderer.render(article.body) return article.copy( @@ -85,11 +77,3 @@ internal fun String.translit(): String { mapping[code.toString()] ?: code.toString() }.joinToString(separator = "") } - -fun ArticlesProcessor.Companion.default( - markdownRenderer: MarkdownRenderer -): ArticlesProcessor { - return DefaultArticlesProcessor( - markdownRenderer = markdownRenderer - ) -} diff --git a/app-backend/src/main/kotlin/usecases/articles/MarkdownRenderer.kt b/app-backend/src/main/kotlin/usecases/articles/MarkdownRenderer.kt new file mode 100644 index 000000000..50d4db97c --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/articles/MarkdownRenderer.kt @@ -0,0 +1,14 @@ +package usecases.articles + +import org.commonmark.parser.Parser +import org.commonmark.renderer.Renderer + +class MarkdownRenderer( + private val parser: Parser, + private val renderer: Renderer +) { + fun render(md: String): String { + val document = parser.parse(md) + return renderer.render(document) + } +} diff --git a/src/main/kotlin/link/kotlin/scripts/PagesGenerator.kt b/app-backend/src/main/kotlin/usecases/articles/PagesGenerator.kt similarity index 60% rename from src/main/kotlin/link/kotlin/scripts/PagesGenerator.kt rename to app-backend/src/main/kotlin/usecases/articles/PagesGenerator.kt index caff0e47c..ec11a8478 100644 --- a/src/main/kotlin/link/kotlin/scripts/PagesGenerator.kt +++ b/app-backend/src/main/kotlin/usecases/articles/PagesGenerator.kt @@ -1,52 +1,72 @@ -package link.kotlin.scripts +package usecases.articles -import link.kotlin.scripts.dsl.Article -import link.kotlin.scripts.dsl.ArticleFeature -import link.kotlin.scripts.dsl.ArticleFeature.highlightjs -import link.kotlin.scripts.dsl.ArticleFeature.mathjax -import link.kotlin.scripts.dsl.LinkType.article -import link.kotlin.scripts.dsl.LanguageCodes.EN -import link.kotlin.scripts.utils.writeFile +import infra.ktor.KtorRoute +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.server.response.respondText +import io.ktor.server.routing.Route +import io.ktor.server.routing.get import java.time.LocalDate import java.time.format.DateTimeFormatter import java.time.format.FormatStyle -interface PagesGenerator { - fun generate(articles: List
, dist: String) +class PagesIndexRoute( + private val articlesSource: ArticleSource, + private val pagesGenerator: PagesGenerator, +) : KtorRoute { + override fun Route.install() { + get("/articles") { + val articles = articlesSource.getArticles() + val articleBody = articles + .groupBy { formatDate(it.date) } + .map { """
${it.key}
    ${getGroupLinks(it.value)}
""" } + .joinToString(separator = "\n") - companion object -} - -private class DefaultPagesGenerator : PagesGenerator { - override fun generate(articles: List
, dist: String) { - val articleBody = articles - .groupBy { formatDate(it.date) } - .map { """
${it.key}
    ${getGroupLinks(it.value)}
""" } - .joinToString(separator = "\n") + val article = Article( + title = "Articles Index", + url = "https://kotlin.link/articles", + body = articleBody, + author = "Ruslan Ibragimov", + date = LocalDate.now(), + type = LinkType.article, + categories = listOf("Kotlin"), + features = listOf(), + filename = "index.html", + lang = LanguageCodes.EN, + description = articleBody + ) - val article = Article( - title = "Articles Index", - url = "https://kotlin.link/articles/", - body = articleBody, - author = "Ruslan Ibragimov", - date = LocalDate.now(), - type = article, - categories = listOf("Kotlin"), - features = listOf(), - filename = "index.html", - lang = EN, - description = articleBody - ) + call.respondText(pagesGenerator.generate(article), ContentType.Text.Html) + } + } +} +class PagesRoute( + private val articlesSource: ArticleSource, + private val pagesGenerator: PagesGenerator, +) : KtorRoute { + override fun Route.install() { + get("/articles/{article}") { + val article = articlesSource.getArticles() + .find { it.filename == call.parameters["article"] } - (articles + article).forEach { - writeFile("$dist/articles/${it.filename}", getHtml(it)) + if (article == null) { + call.respondText("Not found", ContentType.Text.Plain, status = HttpStatusCode.NotFound) + } else { + call.respondText(pagesGenerator.generate(article), ContentType.Text.Html) + } } } } +class PagesGenerator { + fun generate(article: Article): String { + return getHtml(article) + } +} + private fun getGroupLinks(group: List
): String { return group.joinToString(separator = "\n") { - """
  • ${it.title}
  • """ + """
  • ${it.title}
  • """ } } @@ -123,8 +143,8 @@ private fun getHtml(article: Article): String { fun getFeatures(features: List): String { return features.joinToString(separator = "\n") { when (it) { - mathjax -> """""" - highlightjs -> """ + ArticleFeature.mathjax -> """""" + ArticleFeature.highlightjs -> """ @@ -132,7 +152,3 @@ fun getFeatures(features: List): String { } } } - -fun PagesGenerator.Companion.default(): PagesGenerator { - return DefaultPagesGenerator() -} diff --git a/app-backend/src/main/kotlin/usecases/github/AuthGithubRedirectRoute.kt b/app-backend/src/main/kotlin/usecases/github/AuthGithubRedirectRoute.kt index 6af7d0018..c3bfc95f2 100644 --- a/app-backend/src/main/kotlin/usecases/github/AuthGithubRedirectRoute.kt +++ b/app-backend/src/main/kotlin/usecases/github/AuthGithubRedirectRoute.kt @@ -3,12 +3,12 @@ package usecases.github import io.ktor.http.* import io.ktor.server.response.* import io.ktor.server.routing.* -import ktor.KtorRoute +import infra.ktor.KtorRoute class GithubRedirectRoute( private val githubRedirectUrl: GithubRedirectUrl, ) : KtorRoute { - override fun Routing.install() { + override fun Route.install() { get("/auth/github/redirect") { call.response.header(HttpHeaders.Location, githubRedirectUrl()) call.respond(HttpStatusCode.Found) diff --git a/app-backend/src/main/kotlin/usecases/github/GithubAccessToken.kt b/app-backend/src/main/kotlin/usecases/github/GithubAccessToken.kt index edda9cf22..ebbb58e9a 100644 --- a/app-backend/src/main/kotlin/usecases/github/GithubAccessToken.kt +++ b/app-backend/src/main/kotlin/usecases/github/GithubAccessToken.kt @@ -12,8 +12,11 @@ class GithubAccessToken( private val githubAuthConfig: GithubAuthConfig, private val httpClient: HttpClient, ) { - suspend operator fun invoke(p: String): GithubAccessTokenResponse { - return httpClient.post(accessTokenUrl(p)) + suspend operator fun invoke( + code: String, + ): GithubAccessTokenResponse { + return httpClient + .post(accessTokenUrl(code)) .body() } diff --git a/app-backend/src/main/kotlin/usecases/github/GithubAuthRoute.kt b/app-backend/src/main/kotlin/usecases/github/GithubAuthRoute.kt index 3ba3b2ba0..2fb2e2435 100644 --- a/app-backend/src/main/kotlin/usecases/github/GithubAuthRoute.kt +++ b/app-backend/src/main/kotlin/usecases/github/GithubAuthRoute.kt @@ -1,23 +1,25 @@ package usecases.github import io.ktor.server.response.* -import io.ktor.server.routing.Routing import io.ktor.server.routing.get -import ktor.KtorRoute +import infra.ktor.KtorRoute +import io.ktor.http.* +import io.ktor.server.routing.Route class GithubCallbackRoute( private val githubAccessToken: GithubAccessToken, ) : KtorRoute { - override fun Routing.install() { + override fun Route.install() { get("/auth/github") { val code = call.request.queryParameters["code"] ?: error("No code provided") val accessToken = githubAccessToken(code) - println(accessToken) - - call.respond("Hello, Github! $accessToken") + // set cookie and redirect + call.response.cookies.append("accessToken", "Bearer $accessToken") + call.response.headers.append(HttpHeaders.Location, "/") + call.respond(HttpStatusCode.TemporaryRedirect) } } } diff --git a/app-backend/src/main/kotlin/usecases/github/GithubModule.kt b/app-backend/src/main/kotlin/usecases/github/GithubModule.kt index b6e867d70..41b33d190 100644 --- a/app-backend/src/main/kotlin/usecases/github/GithubModule.kt +++ b/app-backend/src/main/kotlin/usecases/github/GithubModule.kt @@ -1,41 +1,41 @@ package usecases.github -import ConfigModule -import HttpClientModule -import io.heapy.komok.tech.di.delegate.bean -import kotlinx.serialization.hocon.Hocon -import kotlinx.serialization.hocon.decodeFromConfig +import infra.config.ConfigModule +import infra.HttpClientModule +import infra.config.decode +import io.heapy.komok.tech.di.lib.Module +@Module open class GithubModule( private val configModule: ConfigModule, private val httpClientModule: HttpClientModule, ) { - open val githubAuthConfig by bean { - Hocon.decodeFromConfig(configModule.config.value.getConfig("github")) + open val githubAuthConfig: GithubAuthConfig by lazy { + configModule.decode("github_auth", GithubAuthConfig.serializer()) } - open val githubRedirectUrl by bean { + open val githubRedirectUrl by lazy { GithubRedirectUrl( - githubAuthConfig = githubAuthConfig.value, + githubAuthConfig = githubAuthConfig, ) } - open val githubRedirectRoute by bean { + open val githubRedirectRoute by lazy { GithubRedirectRoute( - githubRedirectUrl = githubRedirectUrl.value, + githubRedirectUrl = githubRedirectUrl, ) } - open val githubAccessToken by bean { + open val githubAccessToken by lazy { GithubAccessToken( - githubAuthConfig = githubAuthConfig.value, - httpClient = httpClientModule.httpClient.value, + githubAuthConfig = githubAuthConfig, + httpClient = httpClientModule.httpClient, ) } - open val githubCallbackRoute by bean { + open val githubCallbackRoute by lazy { GithubCallbackRoute( - githubAccessToken = githubAccessToken.value, + githubAccessToken = githubAccessToken, ) } } diff --git a/app-backend/src/main/kotlin/usecases/github_trending/GithubConfig.kt b/app-backend/src/main/kotlin/usecases/github_trending/GithubConfig.kt new file mode 100644 index 000000000..27c38c606 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/github_trending/GithubConfig.kt @@ -0,0 +1,8 @@ +package usecases.github_trending + +import kotlinx.serialization.Serializable + +@Serializable +data class GithubConfig( + val token: String, +) diff --git a/src/main/kotlin/link/kotlin/scripts/GithubTrending.kt b/app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSource.kt similarity index 54% rename from src/main/kotlin/link/kotlin/scripts/GithubTrending.kt rename to app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSource.kt index f4de3fd70..120048ca5 100644 --- a/src/main/kotlin/link/kotlin/scripts/GithubTrending.kt +++ b/app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSource.kt @@ -1,12 +1,9 @@ -package link.kotlin.scripts +package usecases.github_trending -import link.kotlin.scripts.dsl.Category -import link.kotlin.scripts.dsl.Subcategory -import link.kotlin.scripts.model.Link -import link.kotlin.scripts.utils.Cache import org.jsoup.Jsoup -import java.time.LocalDate -import java.time.format.DateTimeFormatter +import usecases.links.Category +import usecases.links.Link +import usecases.links.Subcategory private val trending = listOf( "Monthly" to "https://github.com/trending/kotlin?since=monthly", @@ -14,32 +11,8 @@ private val trending = listOf( "Daily" to "https://github.com/trending/kotlin?since=daily" ) -interface GithubTrending { - suspend fun fetch(): Category? - - companion object -} - -private class CachedGithubTrending( - private val cache: Cache, - private val githubTrending: GithubTrending -) : GithubTrending { - override suspend fun fetch(): Category? { - val date = DateTimeFormatter.BASIC_ISO_DATE.format(LocalDate.now()) - val cacheKey = "github-trending-$date" - val cacheValue = cache.get(cacheKey, Category::class) - - return if (cacheValue == null) { - val result = githubTrending.fetch() - result ?: cache.put(cacheKey, result) - result - } else cacheValue - } -} - -private class JSoupGithubTrending( -) : GithubTrending { - override suspend fun fetch(): Category? { +class GithubTrendingLinkSource { + fun fetch(): Category? { val subcategories = trending.mapNotNull { it.toSubcategory() } .deleteDuplicates() .toMutableList() @@ -84,18 +57,3 @@ private class JSoupGithubTrending( } } } - -suspend fun main() { - println(JSoupGithubTrending().fetch()) -} - -fun GithubTrending.Companion.default( - cache: Cache -): GithubTrending { - val jSoupGithubTrending = JSoupGithubTrending() - - return CachedGithubTrending( - cache = cache, - githubTrending = jSoupGithubTrending - ) -} diff --git a/app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSourceModule.kt b/app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSourceModule.kt new file mode 100644 index 000000000..b19260690 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/github_trending/GithubTrendingLinkSourceModule.kt @@ -0,0 +1,18 @@ +package usecases.github_trending + +import infra.config.ConfigModule +import infra.config.decode +import io.heapy.komok.tech.di.lib.Module + +@Module +open class GithubTrendingLinkSourceModule( + private val configModule: ConfigModule, +) { + open val githubTrendingLinkSource by lazy { + GithubTrendingLinkSource() + } + + open val githubConfig: GithubConfig by lazy { + configModule.decode("github", GithubConfig.serializer()) + } +} diff --git a/app-backend/src/main/kotlin/usecases/healthcheck/HealthCheckRoute.kt b/app-backend/src/main/kotlin/usecases/healthcheck/HealthCheckRoute.kt new file mode 100644 index 000000000..a4590e16b --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/healthcheck/HealthCheckRoute.kt @@ -0,0 +1,17 @@ +package usecases.healthcheck + +import io.ktor.server.response.respondText +import io.ktor.server.routing.* +import infra.ktor.KtorRoute + +class HealthCheckRoute : KtorRoute { + override fun Route.install() { + get("/healthcheck") { + call.respondText( + text = """{"status":"ok"}""", + contentType = io.ktor.http.ContentType.Application.Json, + ) + } + } +} + diff --git a/app-backend/src/main/kotlin/usecases/healthcheck/HealthcheckModule.kt b/app-backend/src/main/kotlin/usecases/healthcheck/HealthcheckModule.kt new file mode 100644 index 000000000..287ec2061 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/healthcheck/HealthcheckModule.kt @@ -0,0 +1,10 @@ +package usecases.healthcheck + +import io.heapy.komok.tech.di.lib.Module + +@Module +open class HealthcheckModule { + open val route by lazy { + HealthCheckRoute() + } +} diff --git a/app-backend/src/main/kotlin/usecases/kug/GetKugsRoute.kt b/app-backend/src/main/kotlin/usecases/kug/GetKugsRoute.kt index 150f548f1..e2b13fbac 100644 --- a/app-backend/src/main/kotlin/usecases/kug/GetKugsRoute.kt +++ b/app-backend/src/main/kotlin/usecases/kug/GetKugsRoute.kt @@ -2,12 +2,12 @@ package usecases.kug import io.ktor.server.response.* import io.ktor.server.routing.* -import ktor.KtorRoute +import infra.ktor.KtorRoute class GetKugsRoute( private val kugDao: KugDao, ) : KtorRoute { - override fun Routing.install() { + override fun Route.install() { get("/kugs") { call.respond(kugDao.getAll()) } diff --git a/app-backend/src/main/kotlin/usecases/kug/KugDao.kt b/app-backend/src/main/kotlin/usecases/kug/KugDao.kt index 0e9cca7fa..88e916dfc 100644 --- a/app-backend/src/main/kotlin/usecases/kug/KugDao.kt +++ b/app-backend/src/main/kotlin/usecases/kug/KugDao.kt @@ -3,7 +3,7 @@ package usecases.kug import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.Serializable -import serialization.OffsetDateTimeSerializer +import infra.serialization.OffsetDateTimeSerializer import jooq.main.tables.references.KUG import org.jooq.DSLContext import java.time.OffsetDateTime diff --git a/app-backend/src/main/kotlin/usecases/kug/KugModule.kt b/app-backend/src/main/kotlin/usecases/kug/KugModule.kt index 78692609c..1f98e5950 100644 --- a/app-backend/src/main/kotlin/usecases/kug/KugModule.kt +++ b/app-backend/src/main/kotlin/usecases/kug/KugModule.kt @@ -1,36 +1,36 @@ package usecases.kug -import HttpClientModule -import JooqModule -import YamlModule -import io.heapy.komok.tech.di.delegate.bean +import infra.HttpClientModule +import infra.db.JooqModule +import infra.serialization.YamlModule +import io.heapy.komok.tech.di.lib.Module +@Module open class KugModule( private val httpClientModule: HttpClientModule, private val yamlModule: YamlModule, private val jooqModule: JooqModule, ) { - open val kugDownloadService by bean { + open val kugDownloadService by lazy { KugDownloadService( - yaml = yamlModule.yaml.value, - httpClient = httpClientModule.httpClient.value, + yaml = yamlModule.yaml, + httpClient = httpClientModule.httpClient, ) } - open val kugDao by bean { - DefaultKugDao(jooqModule.dslContext.value) + open val kugDao by lazy { + DefaultKugDao(jooqModule.dslContext) } - open val updateKugsRoute by bean { + open val updateKugsRoute by lazy { UpdateKugsRoute( - kugDownloadService = kugDownloadService.value, + kugDownloadService = kugDownloadService, ) } - val getKugRoute by bean { + val getKugRoute by lazy { GetKugsRoute( - kugDao = kugDao.value, + kugDao = kugDao, ) } } - diff --git a/app-backend/src/main/kotlin/usecases/kug/UpdateKugsRoute.kt b/app-backend/src/main/kotlin/usecases/kug/UpdateKugsRoute.kt index b30b25ce8..1f1ea2988 100644 --- a/app-backend/src/main/kotlin/usecases/kug/UpdateKugsRoute.kt +++ b/app-backend/src/main/kotlin/usecases/kug/UpdateKugsRoute.kt @@ -4,12 +4,12 @@ import io.ktor.http.* import io.ktor.server.response.* import io.ktor.server.routing.* import kotlinx.serialization.Serializable -import ktor.KtorRoute +import infra.ktor.KtorRoute class UpdateKugsRoute( private val kugDownloadService: KugDownloadService, ) : KtorRoute { - override fun Routing.install() { + override fun Route.install() { post("/kugs") { kugDownloadService.pull() .map { section -> diff --git a/app-backend/src/main/kotlin/usecases/links/CategoryProcessor.kt b/app-backend/src/main/kotlin/usecases/links/CategoryProcessor.kt new file mode 100644 index 000000000..816ea9770 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/CategoryProcessor.kt @@ -0,0 +1,23 @@ +package usecases.links + +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope + +class CategoryProcessor( + private val linksProcessor: LinksProcessor, +) { + suspend fun process(category: Category): Category = coroutineScope { + val result = category.copy( + subcategories = category.subcategories.map { subcategory -> + subcategory.copy( + links = subcategory.links.map { link -> + async { linksProcessor.process(link) } + }.awaitAll().toMutableList() + ) + }.toMutableList() + ) + + result + } +} diff --git a/app-backend/src/main/kotlin/usecases/links/LinkSourceModel.kt b/app-backend/src/main/kotlin/usecases/links/LinkSourceModel.kt new file mode 100644 index 000000000..3af64970c --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/LinkSourceModel.kt @@ -0,0 +1,43 @@ +package usecases.links + +import kotlinx.serialization.Serializable + +@Serializable +data class Link( + val name: String? = null, + val github: String? = null, + val bitbucket: String? = null, + val kug: String? = null, + val href: String? = null, + val desc: String? = null, + val platforms: List = emptyList(), + val tags: List = emptyList(), + val star: Int? = null, + val update: String? = null, + val archived: Boolean = false, + val unsupported: Boolean = false, + val awesome: Boolean = false, +) + +@Serializable +enum class PlatformType { + ANDROID, + COMMON, + IOS, + JS, + JVM, + NATIVE, + WASM, +} + +@Serializable +data class Subcategory( + val name: String, + val links: MutableList, +) + +@Serializable +data class Category( + val name: String, + val subcategories: MutableList, +) diff --git a/app-backend/src/main/kotlin/usecases/links/Links.kt b/app-backend/src/main/kotlin/usecases/links/Links.kt deleted file mode 100644 index 17f50edab..000000000 --- a/app-backend/src/main/kotlin/usecases/links/Links.kt +++ /dev/null @@ -1,175 +0,0 @@ -package usecases.links - -import io.heapy.komok.tech.di.delegate.bean -import io.ktor.server.response.respond -import io.ktor.server.routing.Routing -import io.ktor.server.routing.get -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import ktor.KtorRoute - -open class LinksModule { - open val linkSource by bean { - LinkSource().get() - } - - open val route by bean { - LinksRoute( - links = linkSource.value, - ) - } -} - -class LinksRoute( - private val links: List, -) : KtorRoute { - override fun Routing.install() { - get("/links") { - val isAwesome = call.request.queryParameters["awesome"].toBoolean() - - val allLinks: List = if (isAwesome) { - links.map { cat -> - val newSub = cat.subcategories - .map { sub -> - sub.copy(links = sub.links.filter { link -> link.awesome }.toMutableList()) - } - .filter { sub -> - sub.links.isNotEmpty() - } - .toMutableList() - - cat.copy(subcategories = newSub) - }.filter { it.subcategories.isNotEmpty() } - .map { category -> category.toDto() } - } else { - links.map { category -> category.toDto() } - } - - call.respond(allLinks) - } - } -} - -class LinkSource { - private val files = listOf( - "Links.json", - "Libraries.json", - "Projects.json", - "Android.json", - "JavaScript.json", - "Native.json", - "UserGroups.json" - ) - - fun get(): List { - return files.map { file -> - val json = LinkSource::class.java - .classLoader - .getResource("links/$file") - .readText() - Json.decodeFromString(json) - } - } -} - -@Serializable -data class LinkV1( - val name: String? = null, - val github: String? = null, - val bitbucket: String? = null, - val kug: String? = null, - val href: String? = null, - val desc: String? = null, - val platforms: List = emptyList(), - val tags: List = emptyList(), - val star: Int? = null, - val update: String? = null, - val archived: Boolean = false, - val unsupported: Boolean = false, - val awesome: Boolean = false -) - -@Serializable -enum class PlatformTypeV1 { - ANDROID, - COMMON, - IOS, - JS, - JVM, - NATIVE, - WASM -} - -@Serializable -data class SubcategoryV1( - val name: String, - val links: MutableList -) - -@Serializable -data class CategoryV1( - val name: String, - val subcategories: MutableList -) - -data class LinkDto( - val name: String, - val href: String, - val desc: String, - val platforms: List, - val tags: Set, - val star: Int? = null, - val update: String? = null, - val state: LinkStateDto -) - -enum class LinkStateDto { - AWESOME, - UNSUPPORTED, - ARCHIVED, - DEFAULT -} - -private fun LinkV1.toDto(): LinkDto { - val state = when { - awesome -> LinkStateDto.AWESOME - archived -> LinkStateDto.ARCHIVED - unsupported -> LinkStateDto.UNSUPPORTED - else -> LinkStateDto.DEFAULT - } - - return LinkDto( - name = name ?: error("Link should have a name [$this]"), - href = href ?: error("Link should have a href [$this]"), - desc = desc ?: "", - platforms = platforms, - tags = tags.toSet(), - star = star, - update = update, - state = state - ) -} - -data class SubcategoryDto( - val name: String, - val links: List -) - -data class CategoryDto( - val name: String, - val subcategories: List -) - -fun CategoryV1.toDto(): CategoryDto { - return CategoryDto( - name = name, - subcategories = subcategories.map { it.toDto() } - ) -} - -private fun SubcategoryV1.toDto(): SubcategoryDto { - return SubcategoryDto( - name = name, - links = links.map { it.toDto() } - ) -} diff --git a/app-backend/src/main/kotlin/usecases/links/LinksChecker.kt b/app-backend/src/main/kotlin/usecases/links/LinksChecker.kt new file mode 100644 index 000000000..a7ea995ea --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/LinksChecker.kt @@ -0,0 +1,25 @@ +package usecases.links + +import io.heapy.komok.tech.logging.Logger +import io.ktor.client.HttpClient +import io.ktor.client.request.head +import io.ktor.http.HttpStatusCode + +class LinksChecker( + private val httpClient: HttpClient, +) { + suspend fun check(url: String) { + try { + + val response = httpClient.head(url) + + if (response.status != HttpStatusCode.OK) { + log.error("[$url]: Response code: ${response.status}.") + } + } catch (e: Exception) { + log.error("Error ({}) checking link [$url].", e.message) + } + } + + private companion object : Logger() +} diff --git a/app-backend/src/main/kotlin/usecases/links/LinksDtoSource.kt b/app-backend/src/main/kotlin/usecases/links/LinksDtoSource.kt new file mode 100644 index 000000000..b06b4b229 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/LinksDtoSource.kt @@ -0,0 +1,11 @@ +package usecases.links + +class LinksDtoSource( + private val linksSource: LinksSource, +) { + suspend fun get(): List { + return linksSource + .getLinks() + .map { it.toDto() } + } +} diff --git a/app-backend/src/main/kotlin/usecases/links/LinksModule.kt b/app-backend/src/main/kotlin/usecases/links/LinksModule.kt new file mode 100644 index 000000000..00dd48d87 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/LinksModule.kt @@ -0,0 +1,83 @@ +package usecases.links + +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule +import com.fasterxml.jackson.module.kotlin.kotlinModule +import infra.HttpClientModule +import io.heapy.komok.tech.di.lib.Module +import org.commonmark.ext.gfm.tables.TablesExtension +import org.commonmark.parser.Parser +import org.commonmark.renderer.html.HtmlRenderer +import usecases.articles.MarkdownRenderer +import usecases.github_trending.GithubTrendingLinkSourceModule + +@Module +open class LinksModule( + private val githubTrendingLinkSourceModule: GithubTrendingLinkSourceModule, + private val httpClientModule: HttpClientModule, +) { + open val linksDtoSource by lazy { + LinksDtoSource( + linksSource = linksSource, + ) + } + + open val linksSource by lazy { + LinksSource( + githubTrendingLinkSource = githubTrendingLinkSourceModule.githubTrendingLinkSource, + categoryProcessor = categoryProcessor, + ) + } + + open val categoryProcessor by lazy { + CategoryProcessor( + linksProcessor = linksProcessor, + ) + } + + open val objectMapper by lazy { + JsonMapper + .builder() + .addModule(kotlinModule()) + .addModule(JavaTimeModule()) + .build() + } + + open val markdownRenderer by lazy { + val extensions = listOf(TablesExtension.create()) + val parser = Parser.builder().extensions(extensions).build() + val renderer = HtmlRenderer.builder().extensions(extensions).build() + + MarkdownRenderer( + parser = parser, + renderer = renderer + ) + } + + open val linksChecker by lazy { + LinksChecker( + httpClient = httpClientModule.httpClient, + ) + } + + open val linksProcessor by lazy { + val defaultLinksProcessor = DefaultLinksProcessor( + githubConfig = githubTrendingLinkSourceModule.githubConfig, + mapper = objectMapper, + httpClient = httpClientModule.httpClient, + linksChecker = linksChecker, + ) + + val markdownLinkProcessor = DescriptionMarkdownLinkProcessor( + markdownRenderer = markdownRenderer + ) + + CombinedLinksProcessors(listOf(defaultLinksProcessor, markdownLinkProcessor)) + } + + open val route by lazy { + LinksRoute( + linksDtoSource = linksDtoSource, + ) + } +} diff --git a/src/main/kotlin/link/kotlin/scripts/LinksProcessor.kt b/app-backend/src/main/kotlin/usecases/links/LinksProcessor.kt similarity index 59% rename from src/main/kotlin/link/kotlin/scripts/LinksProcessor.kt rename to app-backend/src/main/kotlin/usecases/links/LinksProcessor.kt index aff592123..d984b0036 100644 --- a/src/main/kotlin/link/kotlin/scripts/LinksProcessor.kt +++ b/app-backend/src/main/kotlin/usecases/links/LinksProcessor.kt @@ -1,46 +1,51 @@ -package link.kotlin.scripts +package usecases.links import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue -import link.kotlin.scripts.model.ApplicationConfiguration -import link.kotlin.scripts.model.Link -import link.kotlin.scripts.utils.HttpClient -import link.kotlin.scripts.utils.body -import link.kotlin.scripts.utils.logger -import org.apache.http.client.methods.HttpGet +import io.heapy.komok.tech.logging.Logger +import io.ktor.client.HttpClient +import io.ktor.client.request.get +import io.ktor.client.request.head +import io.ktor.client.request.header +import io.ktor.client.statement.bodyAsText +import io.ktor.http.HttpStatusCode +import usecases.articles.MarkdownRenderer +import usecases.github_trending.GithubConfig import java.time.Instant import java.time.LocalDateTime import java.time.ZoneId +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle import java.time.temporal.ChronoUnit interface LinksProcessor { suspend fun process(link: Link): Link - - companion object } -private class DefaultLinksProcessor( - private val configuration: ApplicationConfiguration, +class DefaultLinksProcessor( + private val githubConfig: GithubConfig, private val mapper: ObjectMapper, private val httpClient: HttpClient, - private val linksChecker: LinksChecker + private val linksChecker: LinksChecker, ) : LinksProcessor { private val now: Instant = Instant.now() + internal val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM) + override suspend fun process(link: Link): Link { return when { link.github != null -> { - LOGGER.debug("Fetching star count from github: ${link.github}.") + log.info("Fetching star count from github: ${link.github}.") + val meta = try { - if (!configuration.dryRun) { - getGithubMetadata(link.github) - } else GithubMetadata.DEFAULT + getGithubMetadata(link.github) } catch (e: Exception) { - LOGGER.error("Error ({}) while fetching data for '${link.github}'.", e.message) - GithubMetadata.DEFAULT + log.error("Error ({}) while fetching data for '${link.github}'.", e.message) + GithubMetadata.EMPTY } + link.check() link.copy( @@ -80,27 +85,25 @@ private class DefaultLinksProcessor( private suspend fun Link.check() { if (this.href != null) { - LOGGER.debug("Checking link [${this.href}]") + log.debug("Checking link [${this.href}]") linksChecker.check(this.href) } } private suspend fun getGithubRepoTopics(name: String): List { return try { - val request = HttpGet("https://api.github.com/repos/$name/topics").also { - it.addHeader("Authorization", "token ${configuration.ghToken}") - it.addHeader("Accept", "application/vnd.github.mercy-preview+json") + val response = httpClient.get("https://api.github.com/repos/$name/topics") { + header("Authorization", "token ${githubConfig.token}") + header("Accept", "application/vnd.github.mercy-preview+json") } - val response = httpClient.execute(request) - - if (response.statusLine.statusCode != 200) { - LOGGER.error("[https://github.com/$name]: Response code: ${response.statusLine.statusCode}.") + if (response.status != HttpStatusCode.OK) { + log.error("[https://github.com/$name]: Response code: ${response.status}.") } - mapper.readValue(response.body()).names + mapper.readValue(response.bodyAsText()).names } catch (e: Exception) { - LOGGER.error("Fetching topics from github: [$name]. Error: {}", e.message) + log.error("Fetching topics from github: [$name]. Error: {}", e.message) emptyList() } } @@ -113,27 +116,25 @@ private class DefaultLinksProcessor( stargazersCount = githubRepoInfo?.stargazersCount, pushedAt = githubRepoInfo?.pushedAt, description = githubRepoInfo?.description, - archived = githubRepoInfo?.archived ?: false, + archived = githubRepoInfo?.archived == true, topics = topics ) } private suspend fun getGithubRepoInfo(name: String): GithubRepoResponse? { return try { - val request = HttpGet("https://api.github.com/repos/$name").also { - it.addHeader("Authorization", "token ${configuration.ghToken}") - it.addHeader("Accept", "application/vnd.github.v3+json") + val response = httpClient.get("https://api.github.com/repos/$name") { + header("Authorization", "token ${githubConfig.token}") + header("Accept", "application/vnd.github.v3+json") } - val response = httpClient.execute(request) - - if (response.statusLine.statusCode != 200) { - LOGGER.error("[https://github.com/$name]: Response code: ${response.statusLine.statusCode}.") + if (response.status != HttpStatusCode.OK) { + log.error("[https://github.com/$name]: Response code: ${response.status}.") } - mapper.readValue(response.body()) + mapper.readValue(response.bodyAsText()) } catch (e: Exception) { - LOGGER.error("Fetching star count from github: [$name]. Error: {}", e.message) + log.error("Fetching star count from github: [$name]. Error: {}", e.message) null } } @@ -142,24 +143,26 @@ private class DefaultLinksProcessor( name: String ): BitbucketResponse? { return try { - LOGGER.debug("Fetching star count from bitbucket: $name.") - val request = HttpGet("https://api.bitbucket.org/2.0/repositories/$name/watchers") - val response = httpClient.execute(request).body() + log.debug("Fetching star count from bitbucket: $name.") + val response = httpClient.head("https://api.bitbucket.org/2.0/repositories/$name/watchers") + .bodyAsText() mapper.readValue(response) } catch (e: Exception) { - LOGGER.error("Fetching star count from bitbucket: [$name]. Error: {}", e.message) + log.error("Fetching star count from bitbucket: [$name]. Error: {}", e.message) null } } private val GithubMetadata.unsupported: Boolean get() { - return (this.pushedAt?.isBefore(now.minus(365, ChronoUnit.DAYS)) ?: false) && (this.stargazersCount ?: 100 < 100) + return (this.pushedAt?.isBefore(now.minus(365, ChronoUnit.DAYS)) == true) && (this.stargazersCount ?: 100 < 100) } + + private companion object : Logger() } class DescriptionMarkdownLinkProcessor( - private val markdownRenderer: MarkdownRenderer + private val markdownRenderer: MarkdownRenderer, ) : LinksProcessor { override suspend fun process(link: Link): Link { return if (link.desc != null) { @@ -178,29 +181,6 @@ class CombinedLinksProcessors( } } -private val LOGGER = logger() - -fun LinksProcessor.Companion.default( - configuration: ApplicationConfiguration, - mapper: ObjectMapper, - httpClient: HttpClient, - linksChecker: LinksChecker, - markdownRenderer: MarkdownRenderer -): LinksProcessor { - val defaultLinksProcessor = DefaultLinksProcessor( - configuration = configuration, - mapper = mapper, - httpClient = httpClient, - linksChecker = linksChecker - ) - - val markdownLinkProcessor = DescriptionMarkdownLinkProcessor( - markdownRenderer = markdownRenderer - ) - - return CombinedLinksProcessors(listOf(defaultLinksProcessor, markdownLinkProcessor)) -} - @JsonIgnoreProperties(ignoreUnknown = true) data class BitbucketResponse( val size: Int @@ -229,7 +209,7 @@ data class GithubMetadata( val topics: List ) { companion object { - val DEFAULT = GithubMetadata( + val EMPTY = GithubMetadata( stargazersCount = null, pushedAt = null, description = null, diff --git a/app-backend/src/main/kotlin/usecases/links/LinksRoute.kt b/app-backend/src/main/kotlin/usecases/links/LinksRoute.kt new file mode 100644 index 000000000..4536e0ff8 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/LinksRoute.kt @@ -0,0 +1,33 @@ +package usecases.links + +import infra.ktor.KtorRoute +import io.ktor.server.response.respond +import io.ktor.server.routing.Route +import io.ktor.server.routing.get + +class LinksRoute( + private val linksDtoSource: LinksDtoSource, +) : KtorRoute { + override fun Route.install() { + get("/api/links") { + val links = linksDtoSource.get() + val isAwesome = call.request.queryParameters["awesome"]?.toBoolean() == true + val isKugs = call.request.queryParameters["kugs"]?.toBoolean() == true + val query = call.request.queryParameters["query"] + + val filteredLinks = if (isAwesome) { + if (query != null) { + links.filterByQuery(query) + } else { + links.filterByAwesome() + } + } else if (isKugs) { + links.filterByKug().filterByQuery(query) + } else { + links.filterByQuery(query) + } + + call.respond(filteredLinks) + } + } +} diff --git a/app-backend/src/main/kotlin/usecases/links/LinksSource.kt b/app-backend/src/main/kotlin/usecases/links/LinksSource.kt new file mode 100644 index 000000000..29ad37db6 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/LinksSource.kt @@ -0,0 +1,37 @@ +package usecases.links + +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.json.Json +import usecases.github_trending.GithubTrendingLinkSource + +class LinksSource( + private val githubTrendingLinkSource: GithubTrendingLinkSource, + private val categoryProcessor: CategoryProcessor, +) { + private val links = GlobalScope.async { + getLinksInternal() + } + + suspend fun getLinks(): List { + return links.await() + } + + private suspend fun getLinksInternal(): List { + val json = LinksSource::class.java + .classLoader + .getResource("data/links.json") + .readText() + + val jsonFileLinks = Json + .decodeFromString(ListSerializer(Category.serializer()), json) + + val githubTrendingLinks = listOfNotNull(githubTrendingLinkSource.fetch()) + + val all = jsonFileLinks + githubTrendingLinks + + return all + .map { categoryProcessor.process(it) } + } +} diff --git a/app-backend/src/main/kotlin/usecases/links/LinksV1Model.kt b/app-backend/src/main/kotlin/usecases/links/LinksV1Model.kt new file mode 100644 index 000000000..92ec4fe6d --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/links/LinksV1Model.kt @@ -0,0 +1,110 @@ +package usecases.links + +import kotlinx.serialization.Serializable + +@Serializable +data class LinkDto( + val name: String, + val href: String? = null, + val desc: String? = null, + val platforms: List = emptyList(), + val tags: Set = emptySet(), + val star: Int? = null, + val update: String? = null, + val state: LinkStateDto, +) + +@Serializable +enum class LinkStateDto { + AWESOME, + UNSUPPORTED, + ARCHIVED, + DEFAULT, +} + +@Serializable +data class SubcategoryDto( + val name: String, + val links: List +) + +@Serializable +data class CategoryDto( + val name: String, + val subcategories: List +) + +private fun Link.toDto(): LinkDto { + val state = when { + awesome -> LinkStateDto.AWESOME + archived -> LinkStateDto.ARCHIVED + unsupported -> LinkStateDto.UNSUPPORTED + else -> LinkStateDto.DEFAULT + } + + return LinkDto( + name = name ?: error("Link should have a name [$this]"), + href = href ?: error("Link should have a href [$this]"), + desc = desc ?: "", + platforms = platforms, + tags = tags.toSet(), + star = star, + update = update, + state = state + ) +} + +fun Category.toDto(): CategoryDto { + return CategoryDto( + name = name, + subcategories = subcategories.map { it.toDto() } + ) +} + +private fun Subcategory.toDto(): SubcategoryDto { + return SubcategoryDto( + name = name, + links = links.map { it.toDto() } + ) +} + + +fun List.filterByAwesome(): List { + return this.mapNotNull { category -> + val subcategories = category.subcategories.mapNotNull { subcategory -> + val links = subcategory.links.filter { linkV1 -> + linkV1.state == LinkStateDto.AWESOME + } + + if (links.isNotEmpty()) subcategory.copy(links = links) else null + } + + if (subcategories.isNotEmpty()) category.copy(subcategories = subcategories) else null + } +} + +fun List.filterByKug(): List { + return this.filter { categoryV1 -> + categoryV1.name == "Kotlin User Groups" + } +} + +fun List.filterByQuery(query: String?): List { + return if (query != null) { + val searchTerm = query.lowercase() + + this.mapNotNull { category -> + val subcategories = category.subcategories.mapNotNull { subcategory -> + val links = subcategory.links.filter { link -> + link.name.contains(searchTerm, ignoreCase = true) || + link.desc?.contains(searchTerm, ignoreCase = true) == true || + link.tags.any { tag -> tag.contains(searchTerm, ignoreCase = true) } + } + if (links.isNotEmpty()) subcategory.copy(links = links) else null + } + if (subcategories.isNotEmpty()) category.copy(subcategories = subcategories) else null + } + } else { + this + } +} diff --git a/app-backend/src/main/kotlin/usecases/ping/Ping.kt b/app-backend/src/main/kotlin/usecases/ping/Ping.kt deleted file mode 100644 index e46c2baa8..000000000 --- a/app-backend/src/main/kotlin/usecases/ping/Ping.kt +++ /dev/null @@ -1,19 +0,0 @@ -package usecases.ping - -import io.ktor.resources.Resource -import io.ktor.server.resources.get -import io.ktor.server.response.respondText -import io.ktor.server.routing.Routing -import ktor.KtorRoute - -@Resource("/ping/{name}") -class PingRequest(val name: String) - -class PingRoute : KtorRoute { - override fun Routing.install() { - get { - call.respondText("Pong: ${it.name}") - } - } -} - diff --git a/app-backend/src/main/kotlin/usecases/ping/PingModule.kt b/app-backend/src/main/kotlin/usecases/ping/PingModule.kt deleted file mode 100644 index 6e9811b70..000000000 --- a/app-backend/src/main/kotlin/usecases/ping/PingModule.kt +++ /dev/null @@ -1,9 +0,0 @@ -package usecases.ping - -import io.heapy.komok.tech.di.delegate.bean - -open class PingModule { - open val route by bean { - PingRoute() - } -} diff --git a/src/main/kotlin/link/kotlin/scripts/ReadmeGenerator.kt b/app-backend/src/main/kotlin/usecases/readme/ReadmeGenerator.kt similarity index 97% rename from src/main/kotlin/link/kotlin/scripts/ReadmeGenerator.kt rename to app-backend/src/main/kotlin/usecases/readme/ReadmeGenerator.kt index 74b475b95..d4c661e9f 100644 --- a/src/main/kotlin/link/kotlin/scripts/ReadmeGenerator.kt +++ b/app-backend/src/main/kotlin/usecases/readme/ReadmeGenerator.kt @@ -1,8 +1,8 @@ -package link.kotlin.scripts +package usecases.readme -import link.kotlin.scripts.dsl.Category +import usecases.links.Category -class MarkdownReadmeGenerator { +class ReadmeGenerator { fun generate(links: List): String { val readmeLinks = links.filterNot { it.name == "Kotlin User Groups" } return generateReadme(readmeLinks) diff --git a/app-backend/src/main/kotlin/usecases/readme/ReadmeModule.kt b/app-backend/src/main/kotlin/usecases/readme/ReadmeModule.kt new file mode 100644 index 000000000..f25449d06 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/readme/ReadmeModule.kt @@ -0,0 +1,20 @@ +package usecases.readme + +import io.heapy.komok.tech.di.lib.Module +import usecases.links.LinksModule + +@Module +open class ReadmeModule( + private val linksModule: LinksModule, +) { + open val readmeGenerator by lazy { + ReadmeGenerator() + } + + open val route by lazy { + ReadmeRoute( + readmeGenerator = readmeGenerator, + linksSource = linksModule.linksSource, + ) + } +} diff --git a/app-backend/src/main/kotlin/usecases/readme/ReadmeRoute.kt b/app-backend/src/main/kotlin/usecases/readme/ReadmeRoute.kt new file mode 100644 index 000000000..b798785f0 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/readme/ReadmeRoute.kt @@ -0,0 +1,20 @@ +package usecases.readme + +import infra.ktor.KtorRoute +import io.ktor.http.ContentType +import io.ktor.server.response.respondText +import io.ktor.server.routing.Route +import io.ktor.server.routing.get +import usecases.links.LinksSource + +class ReadmeRoute( + private val readmeGenerator: ReadmeGenerator, + private val linksSource: LinksSource, +) : KtorRoute { + override fun Route.install() { + get("/readme.md") { + val readme = readmeGenerator.generate(linksSource.getLinks()) + call.respondText(readme, ContentType.Text.Plain) + } + } +} diff --git a/app-backend/src/main/kotlin/usecases/reload/LiveReloadModule.kt b/app-backend/src/main/kotlin/usecases/reload/LiveReloadModule.kt new file mode 100644 index 000000000..cb7fbf2d5 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/reload/LiveReloadModule.kt @@ -0,0 +1,20 @@ +package usecases.reload + +import infra.file_watcher.FileMonitorModule +import io.heapy.komok.tech.di.lib.Module +import server.KtorServerModule + +@Module +open class LiveReloadModule( + private val fileMonitorModule: FileMonitorModule, + private val notificationChannelModule: NotificationChannelModule, + private val serverModule: KtorServerModule, +) { + open val liveReloadService by lazy { + LiveReloadService( + fileMonitor = fileMonitorModule.fileMonitor, + notificationChannel = notificationChannelModule.notificationChannel, + serverConfig = serverModule.serverConfig, + ) + } +} diff --git a/app-backend/src/main/kotlin/usecases/reload/LiveReloadService.kt b/app-backend/src/main/kotlin/usecases/reload/LiveReloadService.kt new file mode 100644 index 000000000..695447bdb --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/reload/LiveReloadService.kt @@ -0,0 +1,30 @@ +package usecases.reload + +import infra.file_watcher.FileMonitor +import io.heapy.komok.tech.logging.Logger +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch +import server.KtorServerModule +import java.nio.file.Path + +class LiveReloadService( + private val fileMonitor: FileMonitor, + private val notificationChannel: NotificationChannel, + private val serverConfig: KtorServerModule.ServerConfig, +) { + private val job = SupervisorJob() + + fun start() { + val fileChanges = fileMonitor.monitor(Path.of(serverConfig.reactDistPath)) + + CoroutineScope(job).launch { + for (change in fileChanges) { + log.info("File change detected: $change") + notificationChannel.notifyAll("reload") + } + } + } + + private companion object : Logger() +} diff --git a/app-backend/src/main/kotlin/usecases/reload/NotificationChannel.kt b/app-backend/src/main/kotlin/usecases/reload/NotificationChannel.kt new file mode 100644 index 000000000..b96dc4933 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/reload/NotificationChannel.kt @@ -0,0 +1,36 @@ +package usecases.reload + +import io.heapy.komok.tech.logging.Logger +import io.ktor.websocket.* +import kotlinx.coroutines.channels.SendChannel +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock + +class NotificationChannel { + private val mutex = Mutex() + private val channels = mutableListOf>() + + suspend fun notifyAll(text: String) { + mutex.withLock { + log.info("Notifying all channels: {}", channels.size) + channels.forEachIndexed { idx, channel -> + log.info("Sending message to channel: {}", idx) + channel.send(Frame.Text(text)) + log.info("Message sent to channel: {}", idx) + } + } + } + + suspend fun register(outgoing: SendChannel) { + mutex.withLock { + log.info("Registering new channel") + channels.add(outgoing) + outgoing.invokeOnClose { + log.info("Channel closed") + channels.remove(outgoing) + } + } + } + + private companion object : Logger() +} diff --git a/app-backend/src/main/kotlin/usecases/reload/NotificationChannelModule.kt b/app-backend/src/main/kotlin/usecases/reload/NotificationChannelModule.kt new file mode 100644 index 000000000..5e17fff41 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/reload/NotificationChannelModule.kt @@ -0,0 +1,10 @@ +package usecases.reload + +import io.heapy.komok.tech.di.lib.Module + +@Module +open class NotificationChannelModule { + open val notificationChannel by lazy { + NotificationChannel() + } +} diff --git a/app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtModule.kt b/app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtModule.kt new file mode 100644 index 000000000..6b34868bf --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtModule.kt @@ -0,0 +1,15 @@ +package usecases.robots_txt + +import io.heapy.komok.tech.di.lib.Module +import usecases.web.WebModule + +@Module +open class RobotsTxtModule( + private val webModule: WebModule, +) { + val route by lazy { + RobotsTxtRoute( + externalWebApplicationContext = webModule.externalWebApplicationContext, + ) + } +} diff --git a/app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtRoute.kt b/app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtRoute.kt new file mode 100644 index 000000000..8f90e5eda --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/robots_txt/RobotsTxtRoute.kt @@ -0,0 +1,36 @@ +package usecases.robots_txt + +import io.ktor.http.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import io.ktor.server.util.* +import infra.ktor.KtorRoute +import usecases.web.WebApplicationContext + +class RobotsTxtRoute( + private val externalWebApplicationContext: WebApplicationContext, +) : KtorRoute { + private val sitemapUrl by lazy { + url { + protocol = when (externalWebApplicationContext.protocol) { + "http" -> URLProtocol.HTTP + "https" -> URLProtocol.HTTPS + else -> URLProtocol.HTTPS + } + host = externalWebApplicationContext.host + port = externalWebApplicationContext.port + path("sitemap.xml") + } + } + + override fun Route.install() { + get("/robots.txt") { + call.respondText( + """ + User-agent: * + Sitemap: $sitemapUrl + """.trimIndent() + ) + } + } +} diff --git a/src/main/kotlin/link/kotlin/scripts/RssGenerator.kt b/app-backend/src/main/kotlin/usecases/rss/RssGenerator.kt similarity index 83% rename from src/main/kotlin/link/kotlin/scripts/RssGenerator.kt rename to app-backend/src/main/kotlin/usecases/rss/RssGenerator.kt index 26c252aef..895b6479f 100644 --- a/src/main/kotlin/link/kotlin/scripts/RssGenerator.kt +++ b/app-backend/src/main/kotlin/usecases/rss/RssGenerator.kt @@ -1,4 +1,4 @@ -package link.kotlin.scripts +package usecases.rss import com.rometools.rome.feed.synd.SyndCategoryImpl import com.rometools.rome.feed.synd.SyndContentImpl @@ -7,20 +7,14 @@ import com.rometools.rome.feed.synd.SyndEntryImpl import com.rometools.rome.feed.synd.SyndFeedImpl import com.rometools.rome.feed.synd.SyndImageImpl import com.rometools.rome.io.SyndFeedOutput -import link.kotlin.scripts.dsl.Article +import usecases.articles.Article import java.io.StringWriter import java.time.Instant import java.time.ZoneOffset import java.util.Date -interface RssGenerator { - fun generate(articles: List
    , name: String): String - - companion object -} - -private class DefaultRssGenerator : RssGenerator { - override fun generate(articles: List
    , name: String): String { +class RssGenerator { + fun generate(articles: List
    , name: String): String { val feed = SyndFeedImpl().apply { title = "Kotlin Programming Language" link = "https://kotlin.link/" @@ -41,7 +35,7 @@ private class DefaultRssGenerator : RssGenerator { SyndCategoryImpl().apply { this.name = "Programming" }, SyndCategoryImpl().apply { this.name = "Android" } ) - generator = "Kotlin 1.4.10" + generator = "kotlin.link" publishedDate = Date.from(Instant.now()) entries = articles.map(::toSyndEntry) } @@ -65,8 +59,3 @@ private fun toSyndEntry(article: Article): SyndEntry { } } } - -fun RssGenerator.Companion.default(): RssGenerator { - return DefaultRssGenerator() -} - diff --git a/app-backend/src/main/kotlin/usecases/rss/RssModule.kt b/app-backend/src/main/kotlin/usecases/rss/RssModule.kt new file mode 100644 index 000000000..646a86b59 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/rss/RssModule.kt @@ -0,0 +1,27 @@ +package usecases.rss + +import io.heapy.komok.tech.di.lib.Module +import usecases.articles.ArticlesModule + +@Module +open class RssModule( + private val articlesModule: ArticlesModule, +) { + open val rssRoute by lazy { + RssRoute( + articleSource = articlesModule.articleSource, + rssGenerator = rssGenerator, + ) + } + + open val fullRssRoute by lazy { + FullRssRoute( + articleSource = articlesModule.articleSource, + rssGenerator = rssGenerator, + ) + } + + open val rssGenerator by lazy { + RssGenerator() + } +} diff --git a/app-backend/src/main/kotlin/usecases/rss/RssRoute.kt b/app-backend/src/main/kotlin/usecases/rss/RssRoute.kt new file mode 100644 index 000000000..08a39bb7f --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/rss/RssRoute.kt @@ -0,0 +1,40 @@ +package usecases.rss + +import io.ktor.http.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import infra.ktor.KtorRoute +import usecases.articles.ArticleSource + +class RssRoute( + private val articleSource: ArticleSource, + private val rssGenerator: RssGenerator, +) : KtorRoute { + override fun Route.install() { + get("/rss.xml") { + val articles = articleSource + .getArticles() + .sortedByDescending { it.date } + .take(20) + + val rss = rssGenerator.generate(articles, "rss.xml") + call.respondText(rss, ContentType.Application.Atom.withCharset(Charsets.UTF_8)) + } + } +} + +class FullRssRoute( + private val articleSource: ArticleSource, + private val rssGenerator: RssGenerator, +) : KtorRoute { + override fun Route.install() { + get("/rss-full.xml") { + val articles = articleSource + .getArticles() + .sortedByDescending { it.date } + + val rss = rssGenerator.generate(articles, "rss-full.xml") + call.respondText(rss, ContentType.Application.Atom.withCharset(Charsets.UTF_8)) + } + } +} diff --git a/app-backend/src/main/kotlin/usecases/signup/GenerateJwt.kt b/app-backend/src/main/kotlin/usecases/signup/GenerateJwt.kt index 6cd7b0918..75ab909c3 100644 --- a/app-backend/src/main/kotlin/usecases/signup/GenerateJwt.kt +++ b/app-backend/src/main/kotlin/usecases/signup/GenerateJwt.kt @@ -7,7 +7,9 @@ import java.util.Date class GenerateJwt( private val jwtConfig: JwtModule.JwtConfig, ) { - operator fun invoke(id: String): String { + operator fun invoke( + id: String, + ): String { return JWT.create() .withAudience(jwtConfig.audience) .withIssuer(jwtConfig.issuer) diff --git a/app-backend/src/main/kotlin/usecases/signup/JwtModule.kt b/app-backend/src/main/kotlin/usecases/signup/JwtModule.kt index 8f3b04896..da98fa8ad 100644 --- a/app-backend/src/main/kotlin/usecases/signup/JwtModule.kt +++ b/app-backend/src/main/kotlin/usecases/signup/JwtModule.kt @@ -1,21 +1,24 @@ package usecases.signup -import ConfigModule -import io.heapy.komok.tech.di.delegate.bean +import infra.config.ConfigModule +import com.auth0.jwt.JWT +import com.auth0.jwt.algorithms.Algorithm +import infra.config.decode +import io.heapy.komok.tech.di.lib.Module import kotlinx.serialization.Serializable -import kotlinx.serialization.hocon.Hocon -import kotlinx.serialization.hocon.decodeFromConfig +import java.util.* +@Module open class JwtModule( private val configModule: ConfigModule, ) { - open val jwtConfig by bean { - Hocon.decodeFromConfig(configModule.config.value.getConfig("jwt")) + open val jwtConfig: JwtConfig by lazy { + configModule.decode("jwt", JwtConfig.serializer()) } - open val generateJwt by bean { + open val generateJwt by lazy { GenerateJwt( - jwtConfig = jwtConfig.value, + jwtConfig = jwtConfig, ) } diff --git a/app-backend/src/main/kotlin/usecases/signup/KotlinerDao.kt b/app-backend/src/main/kotlin/usecases/signup/KotlinerDao.kt index 72452376e..841c5eb03 100644 --- a/app-backend/src/main/kotlin/usecases/signup/KotlinerDao.kt +++ b/app-backend/src/main/kotlin/usecases/signup/KotlinerDao.kt @@ -6,8 +6,8 @@ import kotlinx.coroutines.withContext import jooq.main.keys.UNIQUE_KOTLINER_EMAIL import jooq.main.keys.UNIQUE_KOTLINER_NICKNAME import jooq.main.tables.references.KOTLINER -import ktor.plugins.ConstraintViolationException -import ktor.plugins.ConstraintViolationFields +import infra.ktor.features.ConstraintViolationException +import infra.ktor.features.ConstraintViolationFields import org.jooq.DSLContext import org.jooq.exception.DataAccessException import usecases.signup.KotlinerDao.LoginView diff --git a/app-backend/src/main/kotlin/usecases/signup/Login.kt b/app-backend/src/main/kotlin/usecases/signup/Login.kt index 2acd89c62..cd4fdcdec 100644 --- a/app-backend/src/main/kotlin/usecases/signup/Login.kt +++ b/app-backend/src/main/kotlin/usecases/signup/Login.kt @@ -1,37 +1,38 @@ package usecases.signup -import JooqModule +import infra.db.JooqModule import at.favre.lib.crypto.bcrypt.BCrypt -import io.heapy.komok.tech.di.delegate.bean +import io.heapy.komok.tech.di.lib.Module import io.ktor.http.* import io.ktor.server.request.receive import io.ktor.server.response.respond -import io.ktor.server.routing.Routing import io.ktor.server.routing.post import kotlinx.serialization.Serializable -import ktor.KtorRoute -import ktor.plugins.AuthenticationException +import infra.ktor.KtorRoute +import infra.ktor.features.AuthenticationException +import io.ktor.server.routing.Route import kotlin.time.Duration.Companion.days +@Module open class LoginModule( private val jooqModule: JooqModule, private val jwtModule: JwtModule, ) { - open val bcryptVerifier by bean { + open val bcryptVerifier by lazy { BCrypt.verifyer() } - open val kotlinerDao by bean { + open val kotlinerDao by lazy { DefaultKotlinerDao( - dslContext = jooqModule.dslContext.value, + dslContext = jooqModule.dslContext, ) } - open val route by bean { + open val route by lazy { LoginRoute( - generateJwt = jwtModule.generateJwt.value, - bcryptVerifier = bcryptVerifier.value, - kotlinerDao = kotlinerDao.value, + generateJwt = jwtModule.generateJwt, + bcryptVerifier = bcryptVerifier, + kotlinerDao = kotlinerDao, ) } } @@ -41,8 +42,8 @@ class LoginRoute( private val bcryptVerifier: BCrypt.Verifyer, private val kotlinerDao: KotlinerDao, ) : KtorRoute { - override fun Routing.install() { - post("/login") { + override fun Route.install() { + post("/api/login") { val request = call.receive() val db = kotlinerDao.get(request.email) @@ -58,7 +59,7 @@ class LoginRoute( call.response.cookies.append(Cookie( name ="token", value = token, - secure = false, + secure = true, httpOnly = true, maxAge = 30.days.inWholeSeconds.toInt(), path = "/", diff --git a/app-backend/src/main/kotlin/usecases/signup/Register.kt b/app-backend/src/main/kotlin/usecases/signup/Register.kt index fa9cd1f8d..0a7b160ca 100644 --- a/app-backend/src/main/kotlin/usecases/signup/Register.kt +++ b/app-backend/src/main/kotlin/usecases/signup/Register.kt @@ -1,24 +1,25 @@ package usecases.signup -import JooqModule +import infra.db.JooqModule import at.favre.lib.crypto.bcrypt.BCrypt import at.favre.lib.crypto.bcrypt.LongPasswordStrategies -import io.heapy.komok.tech.di.delegate.bean +import io.heapy.komok.tech.di.lib.Module import io.ktor.http.HttpStatusCode import io.ktor.server.request.receive import io.ktor.server.response.respond -import io.ktor.server.routing.Routing import io.ktor.server.routing.post import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.Serializable -import ktor.KtorRoute +import infra.ktor.KtorRoute +import io.ktor.server.routing.Route import java.security.SecureRandom +@Module open class RegisterModule( private val jooqModule: JooqModule, ) { - open val bcryptHasher by bean { + open val bcryptHasher by lazy { BCrypt.with( BCrypt.Version.VERSION_2A, SecureRandom(), @@ -26,14 +27,14 @@ open class RegisterModule( ) } - open val kotlinerDao by bean { - DefaultKotlinerDao(jooqModule.dslContext.value) + open val kotlinerDao by lazy { + DefaultKotlinerDao(jooqModule.dslContext) } - open val route by bean { + open val route by lazy { RegisterRoute( - bcryptHasher = bcryptHasher.value, - kotlinerDao = kotlinerDao.value, + bcryptHasher = bcryptHasher, + kotlinerDao = kotlinerDao, ) } } @@ -42,7 +43,7 @@ class RegisterRoute( private val bcryptHasher: BCrypt.Hasher, private val kotlinerDao: KotlinerDao, ) : KtorRoute { - override fun Routing.install() { + override fun Route.install() { post("/register") { val request = call.receive() diff --git a/src/main/kotlin/link/kotlin/scripts/Sitemap.kt b/app-backend/src/main/kotlin/usecases/sitemap/Sitemap.kt similarity index 96% rename from src/main/kotlin/link/kotlin/scripts/Sitemap.kt rename to app-backend/src/main/kotlin/usecases/sitemap/Sitemap.kt index 7159075e6..396a12f79 100644 --- a/src/main/kotlin/link/kotlin/scripts/Sitemap.kt +++ b/app-backend/src/main/kotlin/usecases/sitemap/Sitemap.kt @@ -1,4 +1,4 @@ -package link.kotlin.scripts +package usecases.sitemap class SitemapUrl(val url: String) diff --git a/app-backend/src/main/kotlin/usecases/sitemap/SitemapGenerator.kt b/app-backend/src/main/kotlin/usecases/sitemap/SitemapGenerator.kt new file mode 100644 index 000000000..2387a3e94 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/sitemap/SitemapGenerator.kt @@ -0,0 +1,43 @@ +package usecases.sitemap + +import io.ktor.http.URLBuilder +import io.ktor.http.URLProtocol +import io.ktor.http.buildUrl +import io.ktor.http.path +import usecases.web.WebApplicationContext + +class SitemapGenerator( + private val externalWebApplicationContext: WebApplicationContext, +) { + private val siteUrl by lazy { + buildUrl { + protocol = when (externalWebApplicationContext.protocol) { + "http" -> URLProtocol.HTTP + "https" -> URLProtocol.HTTPS + else -> URLProtocol.HTTPS + } + host = externalWebApplicationContext.host + port = externalWebApplicationContext.port + } + } + + fun generate(articles: List
    ): String { + return sitemap { + +SitemapUrl(siteUrl.toString()) + + articles.forEach { article -> + +SitemapUrl( + url = URLBuilder(siteUrl) + .apply { + path("articles", article.filename) + } + .toString() + ) + } + } + } +} + +class Article( + val filename: String +) diff --git a/app-backend/src/main/kotlin/usecases/sitemap/SitemapModule.kt b/app-backend/src/main/kotlin/usecases/sitemap/SitemapModule.kt new file mode 100644 index 000000000..8cdc50d89 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/sitemap/SitemapModule.kt @@ -0,0 +1,24 @@ +package usecases.sitemap + +import io.heapy.komok.tech.di.lib.Module +import usecases.articles.ArticlesModule +import usecases.web.WebModule + +@Module +open class SitemapModule( + private val webModule: WebModule, + private val articlesModule: ArticlesModule, +) { + open val sitemapGenerator by lazy { + SitemapGenerator( + externalWebApplicationContext = webModule.externalWebApplicationContext + ) + } + + open val route by lazy { + SitemapRoute( + articleSource = articlesModule.articleSource, + sitemapGenerator = sitemapGenerator + ) + } +} diff --git a/app-backend/src/main/kotlin/usecases/sitemap/SitemapRoute.kt b/app-backend/src/main/kotlin/usecases/sitemap/SitemapRoute.kt new file mode 100644 index 000000000..a69e6a026 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/sitemap/SitemapRoute.kt @@ -0,0 +1,23 @@ +package usecases.sitemap + +import infra.ktor.KtorRoute +import io.ktor.http.ContentType +import io.ktor.http.withCharset +import io.ktor.server.response.respondText +import io.ktor.server.routing.Route +import io.ktor.server.routing.get +import usecases.articles.ArticleSource + +class SitemapRoute( + private val sitemapGenerator: SitemapGenerator, + private val articleSource: ArticleSource, +) : KtorRoute { + override fun Route.install() { + get("/sitemap.xml") { + val articles = articleSource.getArticles().map { + Article(it.filename) + } + call.respondText(sitemapGenerator.generate(articles), ContentType.Application.Xml.withCharset(Charsets.UTF_8)) + } + } +} diff --git a/app-backend/src/main/kotlin/usecases/stars_job/StarsJob.kt b/app-backend/src/main/kotlin/usecases/stars_job/StarsJob.kt new file mode 100644 index 000000000..75854e238 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/stars_job/StarsJob.kt @@ -0,0 +1,53 @@ +package usecases.stars_job + +import io.heapy.komok.tech.di.lib.Module +import io.heapy.komok.tech.logging.Logger +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import infra.lifecycle.LifecycleModule +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.seconds + +class StarsJob { + fun run() { + log.info("Hello, StarsJob!") + } + + private companion object : Logger() +} + +class StarsJobScheduler( + private val starsJob: StarsJob, + private val applicationScope: CoroutineScope, +) { + fun start() { + applicationScope.launch { + delay(5.seconds) + while (true) { + log.info("About to run stars job") + starsJob.run() + log.info("Stars job finished, sleeping for 24 hours") + delay(24.hours) + } + } + } + + private companion object : Logger() +} + +@Module +open class StarsJobModule( + private val lifecycleModule: LifecycleModule, +) { + open val starsJob by lazy { + StarsJob() + } + + open val starsJobScheduler by lazy { + StarsJobScheduler( + starsJob = starsJob, + applicationScope = lifecycleModule.applicationScope, + ) + } +} diff --git a/app-backend/src/main/kotlin/usecases/version/KotlinVersionFetcher.kt b/app-backend/src/main/kotlin/usecases/version/KotlinVersionFetcher.kt index 2cd5a61dc..ada6e3b07 100644 --- a/app-backend/src/main/kotlin/usecases/version/KotlinVersionFetcher.kt +++ b/app-backend/src/main/kotlin/usecases/version/KotlinVersionFetcher.kt @@ -1,10 +1,14 @@ package usecases.version -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import com.fasterxml.jackson.dataformat.xml.XmlMapper import io.ktor.client.HttpClient import io.ktor.client.request.get import io.ktor.client.statement.bodyAsText +import nl.adaptivity.xmlutil.serialization.XML +import infra.cache.buildCache +import io.heapy.komok.tech.logging.Logger +import usecases.version.MavenModel.MavenMetadata +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds /** * Fetch latest kotlin versions from maven central. @@ -15,39 +19,58 @@ interface KotlinVersionFetcher { suspend fun getLatestVersions(branches: List): List } +class CachedVersionFetcher( + private val kotlinVersionFetcher: KotlinVersionFetcher, +) : KotlinVersionFetcher { + private val cache = buildCache { + timeout(30.seconds) + expireAfterWrite(10.minutes) + loader { branches -> + kotlinVersionFetcher.getLatestVersions(branches) + } + } + + override suspend fun getLatestVersions( + branches: List, + ): List { + return cache.get(branches) + } +} + class MavenCentralKotlinVersionFetcher( - private val xmlMapper: XmlMapper, + private val xml: XML, private val httpClient: HttpClient, ) : KotlinVersionFetcher { override suspend fun getLatestVersions( branches: List, ): List { + log.info("Fetching latest kotlin versions from maven central") + val url = "https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/maven-metadata.xml" - val xml = httpClient.get(url).bodyAsText() + val response = httpClient.get(url).bodyAsText() - val metadata = xmlMapper.readValue(xml, MavenMetadata::class.java) + val metadata = xml.decodeFromString(MavenMetadata.serializer(), response) val versions = metadata.versioning.versions - return branches.map { findMax(versions, it) } + return branches.map { + findMax(versions.version, it) + } } - private fun findMax(versions: List, version: String): String { + private fun findMax( + versions: List, + version: String, + ): String { return versions .filter { it.matches(versionRegex) } .filter { it.startsWith(version) } .maxOrNull() ?: "" } - private val versionRegex = Regex("^\\d+.\\d+.\\d+$") + private companion object : Logger() { + private val versionRegex = Regex("^\\d+.\\d+.\\d+$") + } } -@JsonIgnoreProperties("groupId", "artifactId") -data class MavenMetadata( - val versioning: MavenVersioning -) -@JsonIgnoreProperties("latest", "release", "lastUpdated") -data class MavenVersioning( - val versions: List -) diff --git a/app-backend/src/main/kotlin/usecases/version/KotlinVersionModule.kt b/app-backend/src/main/kotlin/usecases/version/KotlinVersionModule.kt index a2e583396..28bba55e5 100644 --- a/app-backend/src/main/kotlin/usecases/version/KotlinVersionModule.kt +++ b/app-backend/src/main/kotlin/usecases/version/KotlinVersionModule.kt @@ -1,17 +1,26 @@ package usecases.version -import HttpClientModule -import XmlModule -import io.heapy.komok.tech.di.delegate.bean +import infra.HttpClientModule +import io.heapy.komok.tech.di.lib.Module +import infra.serialization.XmlModule +@Module open class KotlinVersionModule( private val xmlModule: XmlModule, private val httpClientModule: HttpClientModule, ) { - open val versionFetcher by bean { - MavenCentralKotlinVersionFetcher( - xmlMapper = xmlModule.xmlMapper.value, - httpClient = httpClientModule.httpClient.value, + open val kotlinVersionFetcher: KotlinVersionFetcher by lazy { + CachedVersionFetcher( + kotlinVersionFetcher = MavenCentralKotlinVersionFetcher( + xml = xmlModule.xml, + httpClient = httpClientModule.httpClient, + ) + ) + } + + open val route by lazy { + KotlinVersionRoute( + kotlinVersionFetcher = kotlinVersionFetcher, ) } } diff --git a/app-backend/src/main/kotlin/usecases/version/KotlinVersionRoute.kt b/app-backend/src/main/kotlin/usecases/version/KotlinVersionRoute.kt new file mode 100644 index 000000000..9680b382b --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/version/KotlinVersionRoute.kt @@ -0,0 +1,15 @@ +package usecases.version + +import io.ktor.server.response.* +import io.ktor.server.routing.* +import infra.ktor.KtorRoute + +class KotlinVersionRoute( + private val kotlinVersionFetcher: KotlinVersionFetcher, +) : KtorRoute { + override fun Route.install() { + get("/api/kotlin-versions") { + call.respond(kotlinVersionFetcher.getLatestVersions(listOf("1.9", "2.0"))) + } + } +} diff --git a/app-backend/src/main/kotlin/usecases/version/MavenModel.kt b/app-backend/src/main/kotlin/usecases/version/MavenModel.kt new file mode 100644 index 000000000..abb26ac72 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/version/MavenModel.kt @@ -0,0 +1,38 @@ +package usecases.version + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import nl.adaptivity.xmlutil.serialization.XmlElement +import nl.adaptivity.xmlutil.serialization.XmlSerialName + +object MavenModel { + @Serializable + @SerialName("metadata") + data class MavenMetadata( + @XmlSerialName("versioning") + @XmlElement + val versioning: Versioning, + @XmlElement + val groupId: String, + @XmlElement + val artifactId: String, + ) + + @Serializable + data class Versioning( + @XmlElement + val latest: String, + @XmlElement + val release: String, + @XmlElement + @XmlSerialName("versions") + val versions: Versions, + @XmlElement + val lastUpdated: String + ) + + @Serializable + data class Versions( + val version: List + ) +} diff --git a/app-backend/src/main/kotlin/usecases/web/DeploymentContext.kt b/app-backend/src/main/kotlin/usecases/web/DeploymentContext.kt new file mode 100644 index 000000000..5ab028823 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/web/DeploymentContext.kt @@ -0,0 +1,15 @@ +package usecases.web + +import kotlinx.serialization.Serializable + +@Serializable +class DeploymentContext( + /** + * Internal context, i.e domain/port/protocol in container to build URL for internal services + */ + val internalContext: WebApplicationContext, + /** + * External context, i.e domain/port/protocol in container to build URL for external services + */ + val externalContext: WebApplicationContext, +) diff --git a/app-backend/src/main/kotlin/usecases/web/WebApplicationContext.kt b/app-backend/src/main/kotlin/usecases/web/WebApplicationContext.kt new file mode 100644 index 000000000..ffa19a5a1 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/web/WebApplicationContext.kt @@ -0,0 +1,10 @@ +package usecases.web + +import kotlinx.serialization.Serializable + +@Serializable +class WebApplicationContext( + val host: String, + val port: Int, + val protocol: String, +) diff --git a/app-backend/src/main/kotlin/usecases/web/WebModule.kt b/app-backend/src/main/kotlin/usecases/web/WebModule.kt new file mode 100644 index 000000000..fc9934b20 --- /dev/null +++ b/app-backend/src/main/kotlin/usecases/web/WebModule.kt @@ -0,0 +1,25 @@ +package usecases.web + +import infra.config.ConfigModule +import infra.config.decode +import io.heapy.komok.tech.di.lib.Module + +@Module +open class WebModule( + private val configModule: ConfigModule, +) { + open val internalWebApplicationContext: WebApplicationContext by lazy { + configModule.decode("web.internal", WebApplicationContext.serializer()) + } + + open val externalWebApplicationContext: WebApplicationContext by lazy { + configModule.decode("web.external", WebApplicationContext.serializer()) + } + + open val deploymentContext by lazy { + DeploymentContext( + internalContext = internalWebApplicationContext, + externalContext = externalWebApplicationContext, + ) + } +} diff --git a/app-backend/src/main/kotlin/utils/closeable.kt b/app-backend/src/main/kotlin/utils/closeable.kt deleted file mode 100644 index ade46b89b..000000000 --- a/app-backend/src/main/kotlin/utils/closeable.kt +++ /dev/null @@ -1,10 +0,0 @@ -package utils - -fun AutoCloseable.close(block: () -> Unit) { - try { - this.use {} - } catch (e: Exception) { - logger(block) - .error("Error while closing resource: ${e.message}", e) - } -} diff --git a/app-backend/src/main/kotlin/utils/logging.kt b/app-backend/src/main/kotlin/utils/logging.kt deleted file mode 100644 index db90c494b..000000000 --- a/app-backend/src/main/kotlin/utils/logging.kt +++ /dev/null @@ -1,18 +0,0 @@ -package utils - -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -inline fun logger(): Logger = LoggerFactory.getLogger(T::class.java) - -@Suppress("NOTHING_TO_INLINE") -inline fun logger(noinline lambda: () -> Unit): Logger { - val name = lambda.javaClass.name - val contextName = when { - name.contains("Kt$") -> name.substringBefore("Kt$") - name.contains("$") -> name.substringBefore("$") - else -> name - } - - return LoggerFactory.getLogger(contextName) -} diff --git a/app-backend/src/main/resources/application.conf b/app-backend/src/main/resources/application.conf index 0d28a6435..cc6ed43b6 100644 --- a/app-backend/src/main/resources/application.conf +++ b/app-backend/src/main/resources/application.conf @@ -1,23 +1,41 @@ server { - port = ${AWESOME_SERVER_PORT} - host = "localhost" - gracefulShutdownTimeout = ${AWESOME_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT} + port = ${AWESOME__SERVER__PORT} + host = ${AWESOME__SERVER__HOST} + gracefulShutdownTimeout = ${AWESOME__SERVER__GRACEFUL_SHUTDOWN_TIMEOUT} + reactDistPath = ${AWESOME__SERVER__REACT_DIST_PATH} } jwt { issuer = "https://kotlin.link/" audience = "https://kotlin.link/" realm = "awesome-kotlin/v2" - secret = ${AWESOME_JWT_SECRET} + secret = ${AWESOME__JWT__SECRET} +} + +github_auth { + clientId = ${AWESOME__GITHUB__CLIENT_ID} + clientSecret = ${AWESOME__GITHUB__CLIENT_SECRET} + redirectUri = ${AWESOME__GITHUB__REDIRECT_URL} } github { - clientId = ${AWESOME_GITHUB_CLIENT_ID} - clientSecret = ${AWESOME_GITHUB_CLIENT_SECRET} - redirectUri = ${AWESOME_GITHUB_REDIRECT_URL} + token = ${GH_TOKEN} } jdbc { - port = ${AWESOME_JDBC_PORT} - host = ${AWESOME_JDBC_HOST} + port = ${AWESOME__JDBC__PORT} + host = ${AWESOME__JDBC__HOST} +} + +web { + internal { + host = ${AWESOME__WEB__INTERNAL__HOST} + port = ${AWESOME__WEB__INTERNAL__PORT} + protocol = ${AWESOME__WEB__INTERNAL__PROTOCOL} + } + external { + host = ${AWESOME__WEB__EXTERNAL__HOST} + port = ${AWESOME__WEB__EXTERNAL__PORT} + protocol = ${AWESOME__WEB__EXTERNAL__PROTOCOL} + } } diff --git a/app-backend/src/main/resources/data/articles.json b/app-backend/src/main/resources/data/articles.json new file mode 100644 index 000000000..1f508cb7d --- /dev/null +++ b/app-backend/src/main/resources/data/articles.json @@ -0,0 +1 @@ +[{"title":"From Groovy to Kotlin","url":"https://dkandalov.github.io/groovy/kotlin/2016/06/06/From-Groovy-to-Kotlin.html","body":"\nThis is a write-up of my experience converting source code of [Activity Tracker](https://github.com/dkandalov/activity-tracker) plugin for IntelliJ IDEs from [Groovy](http://www.groovy-lang.org/) to [Kotlin](https://kotlinlang.org/).\n\nIt is written for anyone familiar with Groovy or Kotlin and might be especially relevant if you are considering move from Groovy to Kotlin. Hopefully, it can be interesting for non-Groovy and non-Kotlin people as well.\n\nPlease note that this is not intended to be a thorough comparison or overview of the languages. The only differences mentioned are those which I came across while transforming Groovy code to Kotlin.\n\n#### About migration\n\n[Activity Tracker](https://github.com/dkandalov/activity-tracker) is a proof-of-concept plugin for IntelliJ IDEs to track and record user activity. It keeps all the data locally so you can see and control what is being logged.\n\nIntelliJ plugins are usually written in Java with a bit of xml configs and IntelliJ platform Java API. Activity Tracker is not like that at all. In the first place, it mostly ignores standard xml configuration and uses [LivePlugin](https://github.com/dkandalov/live-plugin) Groovy API instead. From plugin point of view this means that in addition to standard Java APIs it has to interface with LivePlugin Groovy API. Secondly, Activity Tracker was itself written in Groovy.\n\nWriting plugins in Groovy is not a common practice. At the time the main motivation for me was to use programming language more exciting than Java 6. These days IntelliJ uses Java 8 and Kotlin is “officially approved” language for writing plugins. So migrating from Groovy to Kotlin was not only about having fun but also about moving to standard technology.\n\n#### No ‘new’ keyword\n\nUnlike Groovy (and probably most JVM languages) there is no `new` keyword in Kotlin. To create an instance of a class you can just use class name with constructor parameters.\n\nGroovy:\n\n```groovy\nnew ActivityTracker.Config(...)\n```\n\nKotlin:\n\n```kotlin\nActivityTracker.Config(...)\n```\n\n#### No implicit narrowing/widening for numbers\n\nUnlike Groovy (and probably most JVM languages) there is no implicit narrowing/widening conversion for numbers in Kotlin. That is if you have variable of type `Long` you cannot assign `Int` value to it and vice versa.\n\nEven though this might seem strange, it makes perfect sense because `Int` and `Long` classes are not subtypes of each other. The same applies to `Double` and `Float`. Considering how subtle and difficult it can be to find implicit conversion bugs this is probably a good design.\n\n(In case you were wondering about silent number underflow/overflow, it is still there. Works the same way as in Java.)\n\nGroovy:\n\n```groovy\ndef longValue = 123L\ndef intValue = 123\nlongValue = intValue // works ok\n```\n\nKotlin:\n\n```kotlin\nvar longValue = 123L\nvar intValue = 123\nlongValue = intValue // compilation error\nlongValue = intValue.toLong() // works ok\n```\n\n#### Closure type parameters\n\nIn Groovy types and type parameters are optional. You can skip types all together or specify them in when you feel like doing it. I found it useful to always add types to libraries and other APIs which might be heavily used from other code. It works fine except for `Closure` type which has type parameter only for its return value. To be fair, there is `ClosureParams` annotation to specify types for closure inputs, but it’s too painful to use.\n\nIn Kotlin, closures (aka lambdas) have type parameters for inputs and output as you would expect.\n\nGroovy:\n\n```groovy\nprivate updateState(Closure closure) {...}\n// or\nprivate updateState(@ClosureParams(State.class) Closure closure) {...}\n```\n\nKotlin:\n\n```kotlin\nprivate fun updateState(closure: (State) -> State) {...}\n```\n \n#### “With” vs “run” and “apply”\n\nOne of the interesting features in Groovy is `.with` function defined on `Object` class. It takes a closure and executes it with `this` set to target object. The result of `.with` function is the value of the last expression in closure. This can be useful for calling a bunch of methods on object which doesn’t have fluent API.\n\nConfusingly, Kotlin has `with` function which does exactly the same thing except that it cannot be called on object itself. So to replace Groovy `.with` in Kotlin there is `.run` function. In addition, there is the `.apply` function in Kotlin which is like `.run` but returns target object. This is useful for building object trees and avoiding `it` as the last expression in each closure.\n\nGroovy:\n\n```groovy\ndef actionGroup = new DefaultActionGroup().with {\n add(toggleTracking)\n add(new DefaultActionGroup(\"Current Log\", true).with {\n add(showStatistics)\n add(openLogInIde)\n add(openLogFolder)\n addSeparator()\n add(rollCurrentLog)\n add(clearCurrentLog)\n it // <-- meh\n })\n //...\n it // <-- meh\n}\n```\n\nKotlin:\n\n```kotlin\nval actionGroup = DefaultActionGroup().apply {\n add(toggleTracking)\n add(DefaultActionGroup(\"Current Log\", true).apply {\n add(showStatistics)\n add(openLogInIde)\n add(openLogFolder)\n addSeparator()\n add(rollCurrentLog)\n add(clearCurrentLog)\n })\n // ...\n}\n```\n\n#### “Modifying” immutable objects\n\nBoth Groovy and Kotlin can define value-objects classes, i.e. a class with immutable fields and implicitly defined equality and hash code methods. In Groovy it’s a class with `@Immutable` annotation, in Kotlin `data class` definition. One of the things you might want to do with value-object is copy it into new object changing one or more fields.\n\nEven though underlying implementation is different, from user point of view Groovy and Kotlin code looks similar.\n\nGroovy:\n\n```groovy\n@Immutable(copyWith = true)\nstatic final class State {\n boolean isTracking\n boolean trackIdeActions\n}\nnew State(false, false).copyWith(trackIdeActions: true)\n```\n \nKotlin:\n\n```kotlin\ndata class State(\n val isTracking: Boolean,\n val trackIdeActions: Boolean)\nState(false, false).copy(trackIdeActions = true)\n```\n\n#### Groovy getters and setters\n\nWhen referencing getters/setters from Groovy code you can pretend you’re using a public field. So instead of Java-style getter `o.getFoo()`, you can use `o.foo`. And instead of setter `o.setFoo(\"bar\")`, you can do `o.foo = \"bar\"`.\n\nKotlin also has groovy getters/setters, although for instance methods only.\n\nJava:\n\n```java\nActionManager actionManager = ActionManager.getInstance();\nprintln(actionManager.getComponentName());\n```\n\n\nGroovy:\n\n```groovy\ndef actionManager = ActionManager.instance\nprintln(actionManager.componentName)\n```\n \nKotlin:\n\n```kotlin\nval actionManager = ActionManager.getInstance()\nprintln(actionManager.componentName)\n```\n\n#### Method names with spaces\n\nBoth Groovy and Kotlin allow method names with spaces. This might sound like a strange feature but it’s great for naming unit-tests so that you don’t have to choose between camel case, underscores or mixing both.\n\nAnother less practical but much more exciting question is whether any string can be a method name. For Groovy the answer is “yes”. Kotlin seems to be more restrictive.\n\nGroovy:\n\n```groovy\n@Test def \"convert event object into csv line\"() {...}\n@Test def \"\\n\"() {...} // good names are hard\n@Test def \"\"() {...} // the shortest method name ever\n```\n\nKotlin:\n\n```kotlin\n@Test fun `convert event object into csv line`() {...}\n@Test fun `\\n`() {...} // doesn't compile\n@Test fun ``() {...} // doesn't compile\n```\n\n#### Almost optional “return”\n\nIn Groovy the last expression in function/closure is its return value. You can use `return` keyword to return from function earlier, otherwise it’s entirely optional.\n\nIn Kotlin this is more complex. Functions must have `return` keyword while lambdas cannot use `return`. The result of the last expression in lambda is the value that lambda will return. And `return` in lambda means returning from enclosing method.\n\nThere must be good reasons behind this design in Kotlin but why last expression in function needs `return` keyword is a mystery for me.\n\nIn practice, I had no problems with it except when transforming Kotlin lambdas into methods and the other way round because the code has to be modified to add/remove `return`s.\n\n#### Getting Class object\n\nKotlin has its own reflection classes, i.e. in addition to `java.lang.Class` there is `kotlin.reflect.KClass`. This makes sense because Kotlin has language features which do not exist in Java. (For example, you might want to check using reflection if function argument is optional.)\n\nIn Groovy, as far as I know, it’s not possible to check using reflection whether function argument is optional or not. Probably, analyzing Groovy AST is the way to do it.\n\nJava:\n\n```java\nprintln(ActivityTracker.class);\n``` \n\nGroovy:\n\n```groovy\nprintln(ActivityTracker)\n```\n\nKotlin:\n\n```kotlin\nprintln(ActivityTracker::class.java)\n```\n\n#### Appending writer\n\nGroovy has quite a few “helper” methods which are automatically “added” to Java core classes. For example, `withWriterAppend()` method in `ResourceGroovyMethods` class which simplifies appending to a text file using `Writer`.\n\nIn Kotlin there are also quite a few “helper” methods. In particular for IO operations, in `kotlin.io.FileReadWrite` there is `writer()` function. It does almost the right thing except that there is no option to make writer appendable so reproducing Groovy behaviour is somewhat verbose.\n\nJava:\n\n```java\n// Too many lines of code\n```\n\nGroovy:\n\n```groovy\nnew File(statsFilePath).withWriterAppend(\"UTF-8\") { writer ->\n // use writer\n}\n```\n\nKotlin:\n\n```kotlin\nFileOutputStream(File(statsFilePath), true).buffered().writer(utf8).use { writer ->\n // use writer\n}\n```\n \n#### Enhanced Collections and Maps\n\nIn Groovy there are few functions in `DefaultGroovyMethods` class which are automatically added to all collection classes. For example, `collectEntries()` function takes a closure and, assuming the closure returns two-elements arrays, puts them into a map with first element as a entry key and second element as its value. Or `sort()` function which take a closure and returns sorted collection or even a sorted map.\n\nKotlin has many similar functions available on collections and maps. There are few subtle differences though. Similar to Groovy `collectEntries()` Kotlin has `associateBy()` function but it’s only available on collections, not on maps. This makes it harder to convert one map into another. Another example is `sortBy()` function which in Kotlin exists only on collections and not maps.\n\n(Note that except for few difference the code below is almost identical.)\n\nGroovy:\n\n```groovy\ndef eventsByFile = events\n .findAll{ it.eventType == \"IdeState\" && it.focusedComponent == \"Editor\" && it.file != \"\" }\n .groupBy{ it.file }\n .collectEntries{ [fileName(it.key), it.value.size()] }\n\n// OMG, map sorted by its own value\neventsByFile.sort{ it.value }\n```\n\nKotlin:\n\n```kotlin\nval eventsByFile = events\n .filter{ it.eventType == \"IdeState\" && it.focusedComponent == \"Editor\" && it.file != \"\" }\n .groupBy{ it.file }.toList()\n .associateBy({ it.first }, { it.second.size })\n\neventsByFile\n .map{ Pair(fileName(it.key), it.value.size)}\n .sortedBy{ it.second }\n```\n\n#### Same class in different class loaders\n\nOn JVM class loaders work somewhat like “namespaces”. For example, if you load exactly the same bytecode for a class in two different class loaders, then instances of the class won’t be assignable between the class loaders.\n\nIn Groovy this is still true but since Groovy is an optionally typed language, you can skip types and use object from another class loader calling methods dynamically. This is not a feature you would use every day but it can be useful.\n\nSince Kotlin is statically typed language there is no workaround (except for some verbose reflection magic). To be precise, Kotlin has [dynamic types](https://kotlinlang.org/docs/reference/dynamic-type.html) but they are only supported for JavaScript, and not available on JVM.\n\nGroovy:\n\n```groovy\nprivate updateState(Closure closure) {\n // note that parameter class is commented out because on plugin reload it will\n // be a different type (since it's loaded in new classloader)\n stateVar.set { /*State*/ oldValue ->\n def newValue = closure.call(oldValue)\n onUpdate(oldValue, newValue)\n newValue\n }\n}\n```\n\nKotlin:\n\n```kotlin\n// Can't do this :(\n// The workaround is to convert object to/from instance of a class\n// from parent class loader, e.g. java.lang.String.\n```\n\n#### Extending Groovy interfaces/classes in Kotlin\n\nIf you plan to use Groovy API from Kotlin, be aware that it doesn’t work very well at the moment. Basically, Kotlin compiler doesn’t see method implementations of `groovy.lang.GroovyObject` generated by Groovy.\n\nThe only workaround I found is to manually implement these methods in Kotlin. If you know the answer, I’ll be grateful if you could reply to [this question on Kotlin forum](https://discuss.kotlinlang.org/t/extending-groovy-class-from-kotlin/1675).\n\nGroovy:\n\n```groovy\nclass MyGroovyClass {\n def foo() {}\n}\n```\n\nKotlin:\n\n```kotlin\n// compilation fails with:\n// Object must be declared abstract or implement abstract base\n// class member public abstract fun setProperty(p0: String!, p1: Any!): Unit\nobject : MyGroovyClass() {\n override fun foo() {}\n}\n```\n\nJava:\n\n```java\n// yes, this works fine in Java\nnew MyGroovyClass() {\n @Override public Object foo() {\n return super.foo();\n }\n};\n```\n\n#### Summary\n\nKotlin was created few years after Groovy and borrowed some features from it so when switching from Groovy, Kotlin feels like “a language I almost know”.\n\nBeing statically typed, Kotlin might have a bit more “resistance” than Groovy. On the other hand, it seems to be more suitable for writing “big legacy enterprise projects”.\n\nIf you expected opinion about which language is better, sorry there won’t be one. Both Groovy and Kotlin are good.\n\nTo conclude, here is the final code snippet showing strategically designed Kotlin core libraries:\n\n```kotlin\npublic operator fun times(other: Long): Long\n```\n\n","author":"Dmitry Kandalov","date":"2016-06-06","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Extension Functions Can Be Utility Functions","url":"http://oneeyedmen.com/extension-functions-can-be-utility-functions.html","body":"\nI enjoyed [Extension functions are not utility functions](https://medium.com/@dimsuz/extension-functions-are-not-utility-functions-74a5f9b53892#.o57pbn5k2)\n\nI thought that I disagreed, but on more careful reading maybe not. Instead I’ll pull out some extension functions from my current codebase.\n\nWe’re finding that extension functions are a simple way to make code more expressive.\n\nWithout an extension function:\n\n```kotlin\nprivate fun addressFrom(node: JsonNode): Address = ...\n\nval addresses = nodes.map { addressFrom(it) }\n```\n\nWith an extension function:\n\n```kotlin\nprivate fun JsonNode.toAddress(): Address = ...\n\nval addresses = nodes.map { it.toAddress() }\n```\n\nYou might the find first example more readable like this:\n\n```kotlin\nprivate fun toAddress(node: JsonNode): Address = ...\n\nval addresses = nodes.map(::toAddress)\n```\n\nin which case fill yer boots, but my mind doesn’t work that way.\n\nExtension functions work well here, but the place where they really shine is method chaining.\n\nWithout them:\n\n```kotlin\nprivate fun addressFrom(node: JsonNode): Address = ...\n\nprivate fun isInUK(address: Address): Boolean = ...\n\nval isInUK = isInUK(addressFrom(node))\n```\n\nExtension functions don’t make you turn your brain inside out:\n\n```kotlin\nprivate fun JsonNode.toAddress(): Address = ...\n\nprivate fun Address.isInUK(): Boolean = ...\n\nval isInUK = node.toAddress().isInUK()\n```\n\nYou may have noticed the `private` in the examples above - most of the extension functions that we write this way are used locally - just to make a few lines of code more intuitive. But that’s by no means universally true - this is from some library code to extend Jackson in more general ways:\n\n```kotlin\nfun JsonNode.getExpected(name: String): JsonNode = get(name) ?: throw MissingPropertyException(\"property '$name' is missing\")\n\nfun JsonNode.getNonBlankText(name: String) = getExpected(name).asText().apply {\n if (isBlank()) throw JsonInterpretationException(\"property $name is blank\")\n}\n```\n\nI had wondered whether this style was best suited to operations on types that we don’t own. But I find we have code that acts on our own types:\n\n```kotlin\nfun suggestionsTemplateDataFor(suggestions: List) = mapOf(\n \"results\" to suggestions.withOAText()\n)\n\nprivate fun List.withOAText(): List> = this.map { it.withOAText() }\n\nprivate fun JournalJson.withOAText() = TreeMap(this.asPropertyMap().plus( \"openAccessText\" to this.accessType.toUIString()))\n\nprivate fun AccessType.toUIString() = when (this) {\n AccessType.OPEN_ACCESS -> \"Yes\"\n AccessType.SUBSCRIPTION -> \"No\"\n AccessType.OPEN_CHOICE -> \"Optional\"\n else -> \"Unknown\"\n}\n```\n\nHere `JournalJson` and `AccessType` are simple data classes, unencumbered by all the operations that the rest of the system would like them to have; because they can define operations like `withOAText()` as extension functions when they need them. And if defining an extension on `List` isn’t a utility function I don’t know what is, but here it really helps us to at least get the gist of what is going on at the top level.\n\nHidden in there is a call to\n\n```kotlin\nfun Any.asPropertyMap(): Map = SpaceBlanket(this)\n```\n\nwhich _is_ the archetypal extension function definition - high-level and fundamental.\n\nThere are more thoughts on this subject in a follow up article - [More Kotlin Extension Fun](http://oneeyedmen.com/more-kotlin-extension-fun.html)\n\nIf you like this, [Nat Pryce](www.natpryce.com) and I are going to be talking about Expressive Kotlin at the [Kotlin Night London](https://info.jetbrains.com/Kotlin-Night-London.html) next Wednesday, 12 October 2016.\n\nThanks to [Springer Nature](http://www.springernature.com) for allowing me to publish examples from their code. If you’re looking for a Kotlin job in London, they are hiring - please contact me using one of the links in the sidebar.\n\n","author":"Duncan McGregor","date":"2016-10-05","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"An adventure with Kotlin - Part I","url":"http://angrybyte.me/post/154701023805/kotlin-adventures-1","body":"","author":"Milos Marinkovic","date":"2016-12-20","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin, the somewhat obscure modern Android-friendly programming language","url":"https://medium.com/math-camp-engineering/kotlin-3e963864db9e#.jumx6jh63","body":"\n### Kotlin, the somewhat obscure modern Android-friendly programming language\n\n[Swift](https://developer.apple.com/swift/) is a terse functional programming language with high Objective-C interoperability used for iOS development.\n\nSwift is better than Objective-C.\n\nYou already know this.\n\nBut you probably don’t know what Kotlin is.\n\n[Kotlin](https://kotlinlang.org/) is Swift for Android. [1]\n\nYou’re not using Objective-C anymore, so why are you using Java?\n\nWe built [Roll for Android](http://tryroll.com) in [Kotlin](https://kotlinlang.org/).\n\n### What is Kotlin? Really.\n\nKotlin is a terse swift-like functional programming language on the JVM platform with high Java interoperability. Kotlin is unique in that its standard library and runtime are extremely small in bytes, yet very powerful. Most is eliminated at compile time (in contrast to [Scala](http://www.scala-lang.org/)), so it can feasibly be used in memory “constrained” environments like Android (not embedded systems, but smartphones):\n\n```kotlin\nval immutableVariable = \"a string\"\n\n// a function\nfun inc(x: Int): Int {\n return x+1\n}\n\n// anonymous function bound to a variable\nval inc: (Int) -> Int = { it + 1 }\n```\n\n### Why Kotlin and not “X”?\n\nWe wanted to iterate on a lot of the software structure we came up with for our [Swift iOS app](http://tryroll.com), and for a bunch of pieces we needed a powerful type-system. So rather than just stick with Java — it’s way too verbose — we started looking at alternatives. We wanted a strong static type system, yet the obvious choice, Scala, has too much overhead for Android. Kotlin really stood out for us. [This document by Jake Wharton at Square](https://docs.google.com/document/d/1ReS3ep-hjxWA8kZi0YqDbEhCqTt29hG8P44aA9W0DM8/edit?hl=en&forcehl=1) made the decision easier. So we took the risk.\n\n### Great Features\n\n* [Null type safety!](https://kotlinlang.org/docs/reference/null-safety.html)\n\nIn Kotlin, just like in Swift, optional values are tracked through the type-system. You will not have null pointer exceptions in your Kotlin code:\n\n```kotlin\nval x: String? = tryToGetString()\n// x is not a String (it could be null)\n\nif (x != null) {\n // x is smart-casted to a String here!\n}\n```\n\n* [Lambdas can be inlined!](https://kotlinlang.org/docs/reference/inline-functions.html)\n\nAn under appreciated feature of Kotlin (if you’re targeting Android for example) is the zero overhead higher order functions on collections.\n\nIn Kotlin these standard library functions are inlined and desugared to for-loops.\n\nThus, you can write expressive Scala-like code but without all the anonymous inner class overhead (which while negligible on servers, is [an issue in Dalvik](http://developer.android.com/training/articles/memory.html) and possibly Android’s new runtime ART [no evidence], so Android devices will be affected):\n\n```kotlin\nval strs = listOf(\"this\", \"is\", \"a\", \"bunch\", \"of\", \"words\")\n\nval charCount = strs.map{ it.length }.fold(0, { a, b -> a + b })\n\nval evenWords = strs.filter{ it.length % 2 == 0 }\n```\n\n* [Reified generics!](https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters)\n\nReified generics in Kotlin let you use the generic T in your code at runtime. For example, we’ve used reified generics to implement a clean API for dictionary deserialization to model data classes. Here, we attempt to deserialize an untyped map into some strongly typed data class of type T (like a User):\n\n```kotlin\nprivate inline fun deserialize(dict: Map): T { ... }\n// usage val model = deserialize(modelDataDict)\n```\n\n* [Statically resolved extension functions!](https://kotlinlang.org/docs/reference/extensions.html)\n\nExtension functions in Kotlin allow you to add “methods” to objects. These are resolved statically so there is no performance overhead or runtime confusion.\n\nExtension functions even work on generic “primitives” like Functions or optional types.\n\nFor example, we have defined monadic bind on options (like if-let in Swift if it were an expression and not a statement) and use it all over our codebase [2]:\n\n```kotlin\ninline fun T?.bind(transform: (T) -> R?): R? =\n this?.let(transform)\n```\n\n* [Algebraic data types and pattern matching!](https://kotlinlang.org/docs/reference/classes.html#sealed-classes)\n\nAlgebraic data types or (ADTs) (also called Sum types or tagged unions) allow you model data that can be one of several different variants. Once you’ve used ADTs, you can’t live with out them. The compiler will enforce that you have exhaustively handled all the cases. Swift has them, and as of recently Kotlin does too.\n\nHere is an example of the model for a button that is either disabled, shows a number, or shows info about a user:\n\n```kotlin\nsealed class ButtonState {\n object Disabled: ButtonState()\n class ShowingNum(val num: Int): ButtonState()\n class ShowingPerson(val u: User): ButtonState()\n}\n\n// this state shows 5\nval showFiveState = ShowingNum(5)\n\n// all states handled (enforced by the compiler!)\nfun printbutton(state: ButtonState): String = when (state) {\n is ShowingNum -> \"<{state.num}>\"\n is ShowingPerson -> \"<{state.u.name}>\"\n Disabled -> \"-<>-\"\n}\n```\n\n* Single-method interfaces/classes can be represented as lambdas! aka\n\n```java\nview.setOnClickListener(new View.OnClickListener() {\n @Override public void onClick(View v) {\n /* do something */\n }\n});\n```\n\nbecomes\n\n```kotlin\nview.setOnClickListener { /* do something */ }\n```\n\nThis is great for things like [RxJava](http://reactivex.io/).\n\nSpeaking of which, the Java interoperability is first-class and fantastic. Any Android Java libraries we’ve tried work great from Kotlin.\n\n### Libraries Created\n\nUsing these features, we’ve built:\n\n* a simple dependency injection framework\n* a handful of really useful extensions on things like T? (for example monadic bind)\n* a hack for algebraic data types and pattern matching (before sealed class was released)\n* a single-atom-state functional reactive UI component framework\n* and of course a fairly complex app.\n\nAndroid Studio’s Kotlin support is fantastic (good job JetBrains!) — it’s a pleasure to use.\n\n### Build Time\n\nThe biggest issue for us is the build time. Gradle builds used to take around 5–10 minutes. We invested a week of engineering time in getting a [Buck](https://buckbuild.com/) build working alongside Gradle. Buck builds are 3 minutes max and usually are around 45 seconds. With the most recent Android Studio update, incremental Gradle builds are back down under a minute. This is not too much longer than a pure Java app of our size would take to build.\n\n### Use Kotlin!\n\nKotlin is great! The time saved due to the benefits of Kotlin make up for any time lost optimizing build times.\n\nIf you’re interested in learning more, get in touch. We’re hiring!\n\nNote: this post was adapted from an earlier [HackerNews comment](https://news.ycombinator.com/item?id=9947020)\n\n[1] aside: It is more accurate to say Swift is the Kotlin of iOS since Kotlin has existed in the open for many more years than Swift. Due to Kotlin’s obscurity, however, we’re forced to make the Kotlin to Swift comparison.\n\n[2] Thanks @[daniil_vodopian](https://twitter.com/daniil_vodopian) for the terser bind definition\n\n","author":"Brandon Kase","date":"2016-01-15","type":"article","categories":["Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin VS Java: Basic Syntax Differences","url":"https://yalantis.com/blog/kotlin-vs-java-syntax/","body":"","author":"Irina Galata","date":"2016-12-13","type":"article","categories":["Kotlin","Java"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"A new hope for the JVM: Kotlin","url":"http://engineering.facile.it/blog/eng/kotlin-intro/","body":"\n![Kotlin](http://engineering.facile.it/images/kotlin-intro/logo_Kotlin.svg)\n\n## Premise\n\nJava is an **old** programming language. Version 1.0 was released in 1996 by Sun Microsystems and even though it has evolved and grown a lot over the past twenty years it is still carrying on some bad design choices such as _null_ (ask [Tony Hoare](https://en.wikipedia.org/wiki/Tony_Hoare?section=3#Apologies_and_retractions)), primitive types or lack of a proper function type. With the last version of the language (Java 8) Java tried to address some of these problems introducing concepts such as [`Optional`](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) or [lambda expression](http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html). Although these additions clearly represent a step forward for the language I still have the feeling that they are just _patches_ applied to **mitigate problems** and not to solve them at their very source. For example `Optional` could be used to reduce NPE (Null Pointer Exception) but it is clearly not designed for [this purpose](https://twitter.com/mariofusco/status/780770300178956289) and lambda expressions, implemented in Java 8 with SAM types, still force you to write an interface only to define a _function_.\n\n## The Android world\n\nAll the above concerns about Java are even more problematic within the Android world where, due to the notorious [fragmentation](https://developer.android.com/about/dashboards/index.html) (a huge amount of devices are stuck with an **outdated VM**), you are forced to target lower Java versions (6 and 7). Google is addressing the problem with its new compiler [Jack](https://source.android.com/source/jack.html) that enables _some_ of the features of Java 8 maintaining backward compatibility with older OS versions. But still it lets us deal with the verbosity of the language and it doesn’t truly solve the problem.\n\n## A new hope\n\n![Kotlin Hello World!](http://engineering.facile.it/images/kotlin-intro/kotlin_helloworld.png)\n\nBack in 2011 the JetBrains team (the guys behind IntelliJ and so Android Studio) unveiled [Kotlin](https://kotlinlang.org/), a new programming language that targets the JVM (and can also be compiled to JavaScript). Kotlin is a statically-typed language that combines Object Oriented and functional features enforcing no particular philosophy of programming, and it introduces a whole new set of concepts and tools that helps making the code **safer, cleaner and much more readable**. Thanks to its nature it works everywhere Java do and it is also **interoperable** with it, meaning it will not force you to rewrite the entire codebase to taste it: you can add it to your project a little at a time ([maybe starting with tests](https://medium.com/@sergii/using-kotlin-for-tests-in-android-6d4a0c818776#.lyvd3h43x) \uD83D\uDE09). It also features a REPL `kotlinc-jvm` that allows you to test language features with no effort (see the [doc](https://kotlinlang.org/docs/tutorials/command-line.html#running-the-repl) form more info). I am going to rapidly cover some features of Kotlin that address the previously mentioned Java limitations.\n\n### Null-safety\n\nIn Kotlin **a variable cannot be null**. If you want or need a variable to be _nullable_ you have to add `?` to the variable type:\n\n```kotlin\nval x: Int = null // compile error\nval y: Int? = null // ok\n```\n\nThanks to this information the compiler sees `Int` and `Int?` as two completely different types and can therefore enforce the [null-safety](http://kotlinlang.org/docs/reference/null-safety.html) of your variables. The `?.` allows you to safe call methods on nullable variables without throwing NPE but simply returning null at the end of the call chain:\n\n```kotlin\nval x: Int? = null\nx?.toString()?.substring(2) // no NPE, returns null\n```\n\nThe `?:` operator (Elvis operator) allows you to provide a “default” value when the variable is `null`:\n\n```kotlin\n// The two expressions are semantically equivalent:\ntext?.length ?: -1\n(text.length != null) ? text.length : -1\n```\n\n### Higher-Order Functions and Lambdas\n\nIn Kotlin is possible to declare a method (or more generally a function) that returns or takes another **function as parameter**. The syntax to define the [function type](https://kotlinlang.org/docs/reference/lambdas.html) is similar to other languages such as Scala or Swift and is very **intuitive**:\n\n```kotlin\nval function: (T1, T2) -> R = {t1, t2 -> r}\n```\n\n### Data classes\n\n```kotlin\ndata class City(val name: String, val state: String)\n```\n\n[Data classes](https://kotlinlang.org/docs/reference/data-classes.html) address the verbosity of Java when dealing with classes that have the only purpose to hold data. With a single line you get `equals()/hashCode()`, `toString()` and getters/setters for free (and if you are a Java developer you already knows the benefits!)\n\n# Conclusions\n\nJava has to maintain backward compatibility with previous versions and still has to support the huge amount of developers and codebases present all around the world; therefore it is natural that every new feature and design change is to be considered, weighted and reasoned really carefully, inevitably **slowing down its evolution**. But this does not have to mean that us, as Android developers, “tied” to the JVM, should not try more modern and advanced languages such as Kotlin. At bottom, a part of our job (one of the best!) is to try and **experiment** new technologies and to **learn** new concepts and techniques that improve our ability to address problems in the best possible way (and of course, to have some fun \uD83D\uDE04).\n\nI think that it is fundamental for a software engineer to be **exposed to more than a single programming language**: learning new patterns, exploring other programming paradigms or simply using and understanding a never-seen syntax has an immeasurable value for our growth and most of the times it turns out to be unexpectedly useful even when coding with ”our” language. So why not do it with a language that allows us to continue working on projects targeting our beloved JVM?\n\n","author":"Giacomo Bresciani","date":"2016-10-17","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Exercises in Kotlin: Part 4 - Control flows and return","url":"http://blog.dhananjaynene.com/2016/04/exercises-in-kotlin-part-4-control-flows-and-return/","body":"\nAfter [Exercises in Kotlin: Part 3 - Functions](http://blog.dhananjaynene.com/2016/04/exercises-in-kotlin-part-3-functions/) we now take a look at control flows and actually doing some basic exercises.\n\n## if/else\n\nAs mentioned earlier, `if/else` is not just a statement but can also be used as an operator (in lieu of the ternary `? :` operator.\n\nAs an example, a familiar way to have if/else statements would be as follows.\n\n```kotlin\nfun greeting(hours: Int): String {\n var greeting: String = null\n if (hours < 12) {\n greeting = \"Good Morning\"\n } else if (hours < 16) {\n greeting = \"Good Afternoon\"\n } else {\n greeting = \"Good Night\"\n }\n return greeting\n}\n```\n\nBut since if/else can be an expression as well, another way to write the function above would be\n\n```kotlin\nfun greeting2(hours: Int): String =\n \"Good \" + if (hours < 12) {\n \"Morning\"\n } else if (hours < 16) {\n \"Afternoon\"\n } else {\n \"Night\"\n }\n```\n\n## when\n\nThere is another expression that can be used instead of multiple nested if/else expressions or situations where you might use a switch/case block in Java. Using `when` the function above could be written as\n\n```kotlin\nfun greeting3(hours: Int): String =\n \"Good \" + when {\n hours < 12 -> \"Morning\"\n hours < 16 -> \"Afternoon\"\n else -> \"Night\"\n }\n```\n\nNote that `when` is an expression and evaluates to a value (in the case above it would be \"Morning\", \"Afternoon\" or \"Night\". You could also use it more conventionally just to write other blocks of code eg.\n\n```kotlin\nfun greeting4(hours: Int): Unit {\n when {\n hours < 12 -> {\n println(\"Morning\")\n }\n hours < 16 -> {\n println(\"Afternoon\")\n }\n else -> {\n println(\"Night\")\n }\n }\n}\n```\n\nAs you can note, there is no break statement (unlike switch case), and the right hand side of the conditions can be blocks which consist of multiple statements. If used as a part of a when expression, the value returned by a block is the one returned by the last expression in the block.\n\nWhen used as an expression, the compiler expects the conditions to be exhaustive and thus many times you might need to add an else block. However the else block is not required when used as a statement.\n\nThere are many other things you can do including checking the actual instance or just the value as shown in the rather arbitrary example below\n\n```kotlin\nfun anotherWhen(any: Any): Any =\n when(any) {\n (any is Int && any < 10000) -> \"Small Number\"\n is Int -> \"Big Number\"\n is String -> \"A string\"\n else -> \"Its just another Any\"\n }\n```\n\nYou might note that in the first condition, the right hand side of the condition ie. (any < 10000) actually compiles, because the compiler is able to figure out that any will be an Int if reaches the comparison with 10000 and allows it to be used as an Int. This smart casting is actually quite nice and helps save on verbose typecast statements (or for that matter explicit typecasts) when used in when expressions as above.\n\n## while and do-while\n\nThe familiar constructs of `while` and `do while` are also available. eg.\n\n```kotlin\nfun countDown(n: Int) {\n var counter = n\n while(counter >= 0) {\n println(counter)\n counter--\n }\n}\n```\n\nNote that in kotlin the while block will not allow you to perform an assignment within the while expression unlike java code. eg. `while((n = next()) > 0)` will not compile. In some of these situations you might actually find the `do while` construct useful. eg. the val n declared within the do while block remains in scope while evaluating the while expression.\n\n```kotlin\ndo {\n val n = next()\n // do something\n} while(n > 0)\n```\n\n## for loop\n\nThe for loop is much nicer and often more helpful than in Java. eg. to print each character in a string you could write\n\n```kotlin\nfor(c in \"String\") {\n println(c)\n}\n```\n\nOne of the useful ability of for loop is to iterate over a range which can be written as `startValue..endValue` eg\n\n```kotlin\n// will print 100, 101, 102... 110\nfor (n in 100..110) {\n println(n)\n}\n```\n\nThere are many other aspects of the for loop which are better covered after some other topics, so other sample usages will be taken up later.\n\n## break and continue\n\n`break` and `continue` are also available and continue to have the same meaning as in java. For more advanced uses such as breaking to a or returning to a label, see [Returns and jumps](https://kotlinlang.org/docs/reference/returns.html) from the kotlin reference guide.\n\n## Exercise - Counting Sundays\n\nHere's an exercise for you to try out. (Note: the solution follows immediately after, so you might wish to avoid reading it if you want to attempt to do the exercise yourself first).\n\nThis one comes from [Project Euler](http://blog.dhananjaynene.com/2016/04/exercises-in-kotlin-part-4-control-flows-and-return/) Exercise #19\n\nThe problem is stated as follows\n\n```kotlin\nYou are given the following information, but you may prefer to do some research for yourself.\n\n\n1 Jan 1900 was a Monday.\nThirty days has September,\nApril, June and November.\nAll the rest have thirty-one,\nSaving February alone,\nWhich has twenty-eight, rain or shine.\nAnd on leap years, twenty-nine.\nA leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.\n\nHow many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?\n```\n\nOne of the possible solutions to this problem is described below\n\n```kotlin\nfun sundaysInTwentiethCentury(): Int {\n fun daysInMonth(month: Int, year: Int) = when(month) {\n 1,3,5,7,8,10,12 -> 31\n 4,6,9,11 -> 30\n 2 -> when {\n year % 400 == 0 -> 29\n year % 100 == 0 -> 28\n year % 4 == 0 -> 29\n else -> 28\n }\n else -> throw Exception(\"Invalid Month ${month}\")\n }\n fun daysInYear(year: Int): Int {\n var days = 0\n for(month in 1..12) {\n days += daysInMonth(month, year)\n }\n return days\n }\n fun dayOfWeekAfter(currentDow: Int, numberOfDays: Int) = ((currentDow-1) + numberOfDays) % 7 + 1\n var weekDayOnFirstOfMonth = dayOfWeekAfter(2, daysInYear(1900))\n var totalSundays = 0\n for (year in 1901..2000) {\n for(month in 1..12) {\n if (weekDayOnFirstOfMonth == 1) totalSundays++\n weekDayOnFirstOfMonth = dayOfWeekAfter(weekDayOnFirstOfMonth, daysInMonth(month,year))\n }\n }\n return totalSundays\n}\n```\n\n","author":"Dhananjay Nene","date":"2016-04-27","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin ❤ FP","url":"https://medium.com/@octskyward/kotlin-fp-3bf63a17d64a","body":"\n#### Functional programming in Kotlin, a new language from JetBrains\n\nI did [a video tutorial on FP in Kotlin](http://blog.jetbrains.com/kotlin/2015/11/webinar-recording-functional-programming-with-kotlin/), which can be viewed online.\n\nIf you use .NET you probably heard about F#, a multi-paradigm but essentially functional programming language for the CLR. And you probably heard good things about it. You may also have heard of Haskell, which is similar.\n\nPerhaps you would like languages such as these on the JVM, but with great tool support and without _mandating_ a functional style ... just making it available when you want it.\n\n[**The Kotlin language**](http://kotlinlang.org/) may at first glance appear to be nothing more than an upgraded Java: lots of syntax conveniences, some type inference and so on. But dig a little deeper and you will discover that many of the most popular and advanced features of functional languages are available.\n\nLet’s get started with some simple examples.\n\n* * *\n\n### Algebraic data types\n\nIt’s normal for functional languages to support syntax like this:\n\n```haskell\ndata Maybe a = Nothing | Just a\n deriving (Eq, Ord)\n```\n\nThat’s Haskell, and it defines a type called “Maybe” that has two so called _type constructors_, Nothing and Just. The Just type constructor takes a single parameter of unspecified type. The deriving keyword here means a Maybe can be compared for equality, and ordered. It can also be called a _tagged union_.\n\nKotlin doesn’t need a Maybe type because it has optionality as a built in part of the type system. Optionality is so common in programs that it makes sense to integrate it at a deep level, for both convenience and performance reasons:\n\n```kotlin\nval s: String? = if (Math.random() < 0.5) \"Yay!\" else null\nprintln(\"length of string is .... ${s.length()}\")\n```\n\nHere, we get a compile error on the second line, because we’re trying to read the length of a string we might not actually have, depending on a coin flip. There’s a simple fix:\n\n```kotlin\nval s: String? = if (Math.random() < 0.5) \"Yay!\" else null\nprintln(\"length of string is .... ${s?.length() ?: -1}\")\n```\n\nHere, s?.length() will yield null if s was null, and the ?: operator uses the right hand side if the left hand side is null. So this prints -1 if the coin flip didn’t yield the string.\n\nHowever, we won’t think about that more here.\n\nBecause the Maybe type is so familiar to functional programmers, let’s define an equivalent of it here just for illustration.\n\n```kotlin\nsealed class Maybe {\n object None : Maybe()\n data class Just(val t: T) : Maybe()\n}\n```\n\nThe syntax isn’t as terse as Haskell, but isn’t bad either. The data modifier here is optional, but adding it gives us useful features.\n\nWe can do a variety of functional things with this:\n\n```kotlin\nval j = Maybe.Just(1)\nval (i) = j\n```\n\nHere, we define a “just” containing an integer, and then we destructure it to get the integer back. Notice the lack of types: it’s all inferred. If the type had defined multiple fields, we could [destructure all of them](http://kotlinlang.org/docs/reference/multi-declarations.html), which is how this is actually meant to be used:\n\n```kotlin\ndata class Pet(val name: String, val age: Int)\nval alice = Pet(\"Alice\", 6)\nval (name, age) = alice\n```\n\nWhat about pattern matching? This is where the word “sealed” above comes in handy; we can do an exhaustive pattern match without an else/otherwise branch:\n\n```kotlin\nclass User(val age: Int)\n\nfun lookupFromDB(s: String): Maybe = Maybe.None\n\nfun printUser(username: String) {\n val rec = lookupFromDB(username)\n when (rec) {\n is Maybe.None -> println(\"not found\")\n is Maybe.Just -> println(\"${rec.t.age} years old\")\n }\n}\n```\n\nHere, we define a simple class with a single immutable property (age), and a couple of functions. We have a lookupFromDB function that returns a Maybe: in this case, always a None, but that’s just an example.\n\nThen we use [the when expression](http://kotlinlang.org/docs/reference/control-flow.html#when-expression) to do a pattern match on the type. When expressions are pretty flexible. They can use arbitrary expressions on the left hand side of each case and if the expression is a type query, the code on the right has the cast applied automatically. That’s why we can just access the t property of rec immediately.\n\n### Immutability\n\nKotlin is not a pure FP language and does not have a ‘default’ for mutable vs immutable. It gently encourages immutability in a few places by choice of syntax, but otherwise makes you choose each and every time.\n\nHere’s some code:\n\n```kotlin\ndata class Person(var name: String, var age: Int)\nval p = Person(\"Mike\", 31)\np.name = \"Bob\"\n```\n\nHere “p” is an immutable **val**ue: it cannot be reassigned. It’s like a final variable in Java, or a let expression in Haskell/F#. But then the contents of this structure are mutable **var**iables, so they can be reassigned later. The IDE highlights identifiers differently if they’re mutable.\n\nHere’s how it looks like, fully immutable\n\n```kotlin\ndata class Person(val name: String, val age: Int)\nval mike = Person(\"Mike\", 31)\nval olderMike = mike.copy(age = 32)\n```\n\nThe copy method is auto generated whenever the data modifier is used. It has a named argument for every property, with the default value of that argument being whatever the current value is. Net result, you can use it to create a fresh object with tweaked fields.\n\nLists are immutable by default:\n\n```kotlin\nval people = listOf(mike, olderMike)\npeople.add(Person(\"Bob\", 50)) // ERROR\n\nval peopleDB = arrayListOf(mike, olderMike)\npeopleDB.add(Person(\"Bob\", 50))\n\nval view: List = peopleDB\nval snapshot = peopleDB.toList()\n```\n\nThe second line won’t compile: listOf() returns an immutable list. The fourth line does because we specifically picked an array list (vs a linked list), which is mutable. We can, of course, cast away the mutability to create a read only view, or clone the list to create a snapshot of it.\n\nCurrently there’s no dedicated list literal syntax. There might be in future, but for now, we must use functions.\n\n### Mapping, filtering, reducing etc\n\nKotlin has support for efficient lambdas, and extends the default JDK collections classes to support common functions from FP standard libraries. This can even be used on Java 6 and thus Android:\n\n```kotlin\nval nums = listOf(1, 2, 3, 4)\nval r = nums.map { it * 2 }.sum() // r == 20\n```\n\nHere, the “it” identifier is a convenience: if a lambda has only one argument, it’s called “it” automatically. We can specify an explicit name when “it” would get too confusing, like in nested lambdas.\n\nMap is an _extension function_. Where Java programmers would define a FooUtils class with static methods to add functionality to Foo classes, Kotlin lets you extend the class with a (statically dispatched) method directly. And then it uses that to give Java platform types like Iterable [new features](http://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-iterable/index.html).\n\nA more advanced example:\n\n```kotlin\nval strs = listOf(\"fish\", \"tree\", \"dog\", \"tree\", \"fish\", \"fish\")\nval freqs = strs.groupBy { it }.mapValues { it.value.size() }\nprintln(freqs) // {fish=3, tree=2, dog=1}\n```\n\n### Recursive functions\n\nFunctional programmers like to express solutions to problems using recursion. This often needs an optimisation called _tail call optimisation_ to work well. Kotlin supports this in certain circumstances.\n\nHere’s a simple example. A _fixpoint_ of a mathematical function is an input that gives itself as an output. To find a fixpoint of cosine, you can keep feeding the output back as an input until things stabilise. Here’s an example in an imperative fashion:\n\n```kotlin\nprivate fun cosFixpoint(): Double {\n var x = 1.0\n while (true) {\n val y = Math.cos(x)\n if (x == y) return y\n x = y\n }\n}\n```\n\nPretty simple: starting at 1.0 we keep calling cos until cos(a) == a.\n\nHere’s the same written in a recursive manner:\n\n```kotlin\ntailrec fun cosFixpoint(x: Double = 1.0): Double {\n val r = Math.cos(x)\n return if (x == r) x else cosFixpoint(r)\n}\n```\n\nIt could also be a one liner (or two here, with big fonts):\n\n```kotlin\nimport java.lang.Math.cos\n\ntailrec\nfun f(x: Double = 1.0): Double = if (x == cos(x)) x else f(cos(x)))\n```\n\nThat version relies on the JIT compiler to notice that it can eliminate the duplicated call to Math.cos(x).\n\n### Currying, partial application, composition\n\nThese are features you’ll find in F# and Haskell, though I never felt a need for them myself. Currying turns a function into a chain of functions. Partial application lets you ‘fix’ certain parameters to a function, resulting in a new function.\n\nKotlin doesn’t support these out of the box. But it’s flexible enough that they can be added by [a library called funKtionale](https://github.com/MarioAriasC/funKTionale/wiki), in a natural manner:\n\n```kotlin\nimport org.funktionale.currying.*\n\nval sum2ints = { x: Int, y: Int -> x + y }\nval curried: (Int) -> (Int) -> Int = sum2ints.curried()\nassertEquals(curried(2)(4), 6)\nval add5 = curried(5)\nassertEquals(add5(7), 12)\n```\n\n... and ...\n\n```kotlin\nimport org.funktionale.partials.*\n\nval format = { prefix: String, x: String, postfix: String ->\n \"${prefix}${x}${postfix}\"\n}\n\nval prefixAndBang = format(p3 = \"!\")\n\n// Passing just the first parameter will return a new function\nval hello = prefixAndBang(p1 = \"Hello, \")\n\nprintln(hello(\"world\"))\n```\n\n### Lazyness\n\nKotlin is a strict/eager language, and this is how it should be. As far as I’m aware, no other well known language uses lazy-by-default except Haskell.\n\nHowever you can do lazy computations if you want to. Here’s a dead simple real world example: avoiding the work of building a string if logging is disabled.\n\n```kotlin\nval loggingEnabled = System.getProperty(\"log\") != null\n\nfun log(s: String): Unit = if (loggingEnabled) println(s)\n\nfun log(ls: () -> String): Unit = if (loggingEnabled) println(ls())\n```\n\nThe log function is overloaded: it can take an actual string, or a function that calculates a string:\n\n```kotlin\nlog(\"now!\")\nlog { \"calculate me later\" }\n```\n\nFunctional programming occasionally involves building infinite lists of things and operating on them in a lazy and possibly parallel manner. [This is often seen as a key selling point for FP](http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/STMTokyoApr10.pdf) (see slide 10).\n\nSince version 8 Java can do this too, and therefore so can Kotlin. For example:\n\n```kotlin\nval ONE = BigInteger.ONE\nfun primes(n: Long) =\n Stream.iterate(ONE) { it + ONE }.\n filter { it.isProbablePrime(16) }.\n limit(n).\n toList()\n```\n\nJava calls infinite lazy lists _streams._ Here, we build a list of all the positive BigIntegers. Then we select only the ones that are probably prime numbers with chance 2^16, according to the Miller-Rabin primality test. Then we take _n_ of them and put them into a regular non-lazy list. This is classical functional programming.\n\nHow fast is this?\n\n```kotlin\nrepeat(3) {\n val t = measureTimeMillis {\n primes(100000)\n }\n println(\"Took $t msec\")\n}\n```\n\nOn my laptop, after the first run when the JIT compiler has crunched, it takes about 1.5 seconds.\n\nOne nice thing about pipelines of pure functions is you can parallelise them. Let’s do that now:\n\n```kotlin\nfun primes(n: Long) =\n Stream.iterate(ONE) { it + ONE }.\n parallel().\n filter { it.isProbablePrime(16) }.\n limit(n).\n toArray()\n```\n\nWe inserted a call to parallel() in our stream. This tells the JVM to run the rest of the pipeline in multiple threads. Rerunning the program shows that this improved performance 3x: it now only takes half a second. Not bad!\n\n### STM\n\nSoftware transactional memory is a way to write concurrent code. It is well explained in [this paper by Simon Peyton-Jones](http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/beautiful.pdf), one of the architects of Haskell.\n\nInstead of using locks you write code like this:\n\n```kotlin\nvar account1 = 5\nvar account2 = 0\n\nfun transfer(amount: Int) {\n atomic {\n account1 -= amount\n account2 += amount\n }\n}\n```\n\nFrom the programmers perspective, anything that happens inside the atomic block takes effect all at once when the block is exited and there can be no race conditions inside it. But multiple threads can all be inside the atomic block at once, doing useful work. Pretty neat, right?\n\nA simple implementation would be to have a giant global lock, but that’d be very slow. So fancier implementations record every change made inside the block by threads running concurrently, and detect conflicts: if there is a conflict, the block is retried. Haskell has an implementation of such a thing.\n\nKotlin does not have language support for software transactional memory. However, this is not such a big deal because via the JVM it gets support using libraries like [Scala STM](http://nbronson.github.io/scala-stm/quick_start.html) (see below), and even something better: _hardware_ transactional memory. Yup.\n\nModern (very modern) Intel chips support a set of processor extensions called TSX. TSX allows code to create an atomic transaction at the hardware level. Changes to RAM are buffered up in cache lines and interference between threads is tracked by the CPU itself. If there was a conflict, the CPU aborts the transaction and expects the code to either try again or fall back to regular locking. If no thread bumped into you, your writes are flushed to RAM in one go at the end.\n\nStarting with Java 8 Update 40, so-called “RTM locking” is enabled by default when the CPU supports it. This converts _every_ Java synchronized block into a hardware level atomic transaction using TSX. That means you will have multiple threads running inside synchronized blocks at once. The JVM profiles the app to find blocks that experience frequent thread interference, where the CPU is wasting time due to constantly rolling back/retrying, and converts them back to using regular locks. As Kotlin runs on the JVM it gets this functionality for free.\n\nThis lets you write code in the “one big lock” style without suffering the performance downsides, as long as you are on sufficiently new hardware.\n\nI should note here that STMs often provide extra features, like the ability to pause/retry a code block when the dependencies change, or the ability to explicitly cancel a transaction without retrying it (by throwing an exception). Hardware TM doesn’t offer this, or rather the JVM doesn’t surface the support at the moment. If you want more control, you must use a library and explicitly change your data model to incorporate transactional variables:\n\n```kotlin\nimport scala.concurrent.stm.japi.STM.*\n\nval counter = newRef(10)\ntry {\n atomic {\n increment(counter, 1)\n println(\"counter is ${counter.get()}\") // -> 11\n throw Exception(\"roll back!!\")\n }\n} catch(e: Exception) {\n println(\"counter is ${counter.get()}\") // -> 10\n}\n```\n\nHaskell has one other neat trick up its sleeve —using its type system it can ensure that variables are only accessed inside atomic blocks, so you can never forget to wrap your code up properly. We can do something a bit similar in Kotlin:\n\n```kotlin\nclass ThreadBox(v: T) {\n private val value = v\n @Synchronized fun locked(f: T.() -> R): R = value.f()\n}\n\nval bank = ThreadBox(object {\n val accounts = intArrayOf(10, 0, 0, 0)\n})\n\nfun transfer(from: Int, to: Int, amount: Int) {\n bank.locked {\n accounts[from] -= amount\n accounts[to] += amount\n }\n}\n```\n\n\nA ThreadBox is a simple class that takes a pointer to some object in its constructor. It keeps that pointer privately. So, if there’s no other reference to the passed object it can only be accessed via the ThreadBox. When we declare _bank_, we use the object keyword to create an anonymous object and pass it in — so we know the only way to reach the accounts array is via the ThreadBox. And the ThreadBox only gives out that pointer inside an atomic block.\n\nThe compiler won’t let us access the array outside an atomic block ... unless we let a reference escape. So this is not as strong as the Haskell type system approach, but it’s a good start.\n\nThere’s a version of this code that can catch more mistakes [here](https://gist.github.com/mikehearn/1ad4a9c375e59e52b8cf).\n\nThe atomic method is a higher order function protected by a regular Java synchronized method, and it just immediately calls the provided code block under the lock. The JVM will ignore the lock on hardware that supports TSX and all threads can proceed in parallel, in an atomic transaction. As long as the two threads are using different account IDs for _from_ and _to_, no locking is done at all: that makes it nice and fast.\n\n### Things Kotlin lacks\n\nAt the moment there is no way to control side effects: any function call can be potentially side effecting. It would be nice if a future version of the language introduced something like the C++ const keyword, or D’s transitive const, to reduce the reliance on actually immutable data structures. The JVM offers features that can seal off common sources of external state, such as the disk and network, however the heap is still available. It may be an interesting project to make the JVM’s sandboxing features easily available via a Kotlin DSL.\n\nThere is not at this moment any high performance immutable collections library. Both Clojure and Scala have maps and sets in which mutating the collection returns a new collection, with internal data sharing to make performance practical. The Kotlin standard library does not. If someone were to make one, using [the CHAMP code](http://michael.steindorfer.name/publications/oopsla15.pdf) published this year would give significant improvements over the algorithms used in Scala/Clojure.\n\n","author":"Mike Hearn","date":"2015-09-18","type":"article","categories":["Kotlin","Functional"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin & Android: A Brass Tacks Experiment, Part 4","url":"https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-4-4b7b501fa457#.dllcmjpbu","body":"\n![Header Picture](https://cdn-images-1.medium.com/max/800/1*UN-S8ELMC2kpHf4tJKfbLQ.png)\n\n*Disclaimer: I am a Google employee, but the views expressed in this article are not those of my employer.*\n\n## Kotlin & Android: A Brass Tacks Experiment, Part 4\n\nWelcome to part 4 in this a series! If you missed [part 2](https://medium.com/p/kotlin-android-a-brass-tacks-experiment-part-2-c67661cfdf5f) and [part 3](https://medium.com/p/kotlin-android-a-brass-tacks-experiment-part-3-84e65d567a37), consider jumping back to those for a minute to see where we are in this journey to learn what the Kotlin® language can uniquely offer for Android development.\n\nAt this point, we have a pair of functions that we can use to succinctly express the creation of an entire Android view hierarchy in Kotlin code instead of the usual XML resources. Kotlin’s *type-safe builder* pattern is really shining here! However, in practice, there are still some rough edges with this scheme. Most notably, Android developers are used to having some special expressions in XML for certain Android concepts, such as sizes of Views measured in density independent pixels. This is super easy in XML and super tiresome in code!\n\nHere’s an example of a tiresome way to set the maxWidth property of a TextView to 120dp using our new v function:\n\n\n```kotlin\nval view = v(context) {\n // ugly!\n maxWidth = TypedValue.applyDimension(\n TypedValue.COMPLEX_UNIT_DIP, 120, context.resources.displayMetrics).toInt()\n}\n```\n[gist](https://gist.github.com/CodingDoug/abe3765f9fe641871ede)\n\nContrast that to XML layouts, where you’d simply say:\n\n```xml\n\n```\n[gist](https://gist.github.com/CodingDoug/c239a76530670537ce6b)\n\nBah! We just lost all the convenience that our v functions were trying to gain!\n\n### We need an abbreviated way to convert dp to px.\n\nWhat I’d like is a function to provide shortened syntax for specifying pixel measurements in other units. Here’s what I want to say instead of the above mess:\n\n```kotlin\nval view = v(context) {\n // simpler way to set maxWidth to 120dp\n maxWidth = dp_i(120)\n}\n```\n[gist](https://gist.github.com/CodingDoug/cef8e7f5fe6324ff6436)\n\nWhat I’m proposing here is a function that takes a value measured in dp and returns the value converted to px for the current device. Why call the function “dp_i” and not just “dp”? Sometimes Android wants to take pixel measurements as a floating point number and sometimes as an integer. I don’t want to manually cast the return value (still too many more characters), so I’ll just make one function for of each type, “dp_i” and “dp_f”.\n\nBut there’s a wrinkle here. If you look back at the full code that computes the dp value, it requires a Context to operate. I don’t want to have to pass a Context as another argument to dp_i every time I call it. So I’m going to use a feature of Kotlin called [extension functions](https://kotlinlang.org/docs/reference/extensions.html) to get the brevity I prefer.\n\nLet’s jump right into the code. Written as extension functions, here’s what dp_i and dp_f look like:\n\n```kotlin\nimport android.view.View\n\nfun View.dp_f(dp: Float): Float {\n return TypedValue.applyDimension(\n TypedValue.COMPLEX_UNIT_DIP, dp, context.resources.displayMetrics)\n}\n\nfun View.dp_i(dp: Float): Int {\n return dp_f(dp).toInt()\n}\n```\n[gist](https://gist.github.com/CodingDoug/489045d5a92be732dec9)\n\n### How does an extension function work?\n\nThe first thing to notice in the above code is the apparent name of the functions. You might have expected to see just “dp_f” for the first function, but instead we have “View.dp_f”. This is a special syntax in Kotlin for extension functions. There is a dot between a class name (here, android.view.View) and the name of the function to define. What we did here was tell Kotlin to augment the View class with a new two new methods called “dp_f” and “dp_i”. There’s a couple things you get with extension functions like these.\n\n**First, code in the body of the extension functions can act like a member of View by accessing its members and methods (but only of “public” and “internal” visibility)**. This means that dp_f can use the View’s Context reference as exposed by the synthetic property called “context”. Now we don’t have to pass a Context as a parameter since it comes implicitly with the View.\n\n**Second, other code that imports these extension functions can call them as if they’re normal member methods on instances of View objects**. This means that our v function’s lambda with receiver argument of type View can call these methods similarly to ordinary functions, implicitly using the receiver View object reference. So you can say “maxWidth = dp_i(120)” in the lambda, and Kotlin will recognize that you want to call the dp_i function on the View type receiver object.\n\n**One important thing to know here is that Kotlin doesn’t actually make changes to a class definition when defining an extension function**. A class will always be its own complete unit after it’s been loaded by a program, so we can only use extension functions to add code around it. Also, the existing methods on View also can’t reach back into and extension function, because it’s not a real member defined with the class.\n\nThe upshot of these points, for this experiment, is that we now have convenient functions for converting dp to px in our v function lambdas!\n\n**We’re not stopping here! How about another shortcut using extension functions?**\n\nWe’ve seen that you can do tricky things with extension functions to make some kinds of functions more convenient to use. Let’s continue with that thought to tighten up our v functions.\n\nCurrently, we have these two function signatures, the first for building the root view using a Context and the second for creating nested child views in a parent view:\n\n```kotlin\ninline fun v(context: Context, init: TV.() -> Unit) : TV\n\ninline fun v(parent: ViewGroup, init: TV.() -> Unit) : TV\n```\n[gist](https://gist.github.com/CodingDoug/c91ef8277e3edae1be6e)\n\nIt would be nice if we didn’t have to pass the Context or ViewGroup as the first parameter. With extension functions, we achieve this just like we did above when avoiding passing a Context to dp_f. Here’s a re-implementation of both functions as extension functions, with the commented out lines showing the original code for v above the newly modified lines:\n\n```kotlin\n//inline fun v(context: Context, init: TV.() -> Unit) : TV {\ninline fun Context.v(init: TV.() -> Unit) : TV {\n val constr = TV::class.java.getConstructor(Context::class.java)\n\n // val view = constr.newInstance(context)\n val view = constr.newInstance(this)\n\n view.init()\n return view\n}\n\n//inline fun v(parent: ViewGroup, init: TV.() -> Unit) : TV {\ninline fun ViewGroup.v(init: TV.() -> Unit) : TV {\n\n val constr = TV::class.java.getConstructor(Context::class.java)\n\n // val view = constr.newInstance(parent.context)\n val view = constr.newInstance(context)\n\n parent.addView(view)\n view.init()\n return view\n}\n```\n[gist](https://gist.github.com/CodingDoug/43d17d44459805e51072)\n\nYou can see that we’re removing the first argument to each function (Context and ViewGroup), and instead, expecting those references to come from the instance of the class they are extending. The functions now have just a single argument — the lambda with receiver that modifies the created View.\n\nWith these modified functions, if we’re coding inside an Activity (which is a subclass of Context), we refer to v as a member of the Activity object. We can take advantage of this to build nested views even easier like this:\n\n```kotlin\nv {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n orientation = VERTICAL\n\n v {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n text = \"Hello\"\n }\n v {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n text = \"World\"\n }\n}\n```\n[gist](https://gist.github.com/CodingDoug/3961d2ccc55376cf1274)\n\nThe invocations of v don’t even look like function calls because we no longer need parenthesis at all. If you recall from [part 2 in this series](https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-2-c67661cfdf5f), if the last argument to a function is a lambda, you can place it after the parenthesis. And in this case, when there’s only one argument, you don’t need the parenthesis at all!\n\nKotlin’s extension functions have just gone a long way toward helping us express an Android view hierarchy in a very readable and succinct way in code. However, there’s still some more problem spots that could use some attention. For example, lets take this code that assigns 16dp of left padding to a TextView:\n\n```kotlin\nv {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n setPadding(dp_i(16), 0, 0, 0)\n text = \"Hello\"\n}\n```\n[gist](https://gist.github.com/CodingDoug/6119424973b9c0f3824d)\n\nIt’s pretty ugly to mix a method call to setPadding() with the synthetic property accessors for layoutParams and text. setPadding() is causing us problems here because it’s not a JavaBeans-style setter — it has more than one argument. Therefore, Kotlin can’t assign a synthetic property to it. But fear not! This can be fixed with clever use of another Kotlin language feature, as we’ll discover in the upcoming part 5.\n\nIf you want to stay on top of this series, you can follow me both [here on Medium](https://medium.com/@CodingDoug) and [on Twitter](https://twitter.com/CodingDoug) as CodingDoug and get instant notification of future parts!\n\n","author":"Doug Stevenson","date":"2016-02-04","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin для начинающих","url":"https://habrahabr.ru/post/278277/","body":"\nУже не мало нашумел Kotlin в мире программирования, не мало профессиональных инженеров уже обратил на него внимание, но также есть и те кому он не симпатизирует.\n\n![Kotlin](https://habrastorage.org/files/a52/453/729/a52453729bd64cb3b5ca8a4892e45cc1.png)\n\nВ данном топике я бы хотел обратить внимание тех начинающих программистов которые возможно только делают свой выбор языка программирования, которому бы хотели посвятить свою жизнь так сказать.\n\nЯ сам Java Developer и для меня наступил тот период я когда хотелось посмотреть на другие языки, взять какие-то практики для себя с них.\n\nИ однажды примерно в 2013 году я услышал что та прекрасная компания делающая такие крутые продукты как **Intellij IDEA**, **Youtrack** а именно [JetBrains](https://www.jetbrains.com/), анонсировала о новом языке [Kotlin](https://kotlinlang.org/), который на то время был в активной стадии разработки.\n\nИ в этом году а именно 15 февраля 2016 года был выпушен релиз **Kotlin 1.0**. С этого момента я начал уже более активней его изучать и пытаться применять в небольших свои проектах.\n\n## Kotlin для начинающих\n\nИ этим постом я бы хотел поделится серией видео в которой я начал делится всем тем что я изучил за это время касаемо Kotlin.\n\n**Урок 0. Введение и знакомство**\nhttps://www.youtube.com/watch?v=L9k_NdTaMeI\n\n\n**Урок 1. String Templates**\nhttps://www.youtube.com/watch?v=frw1DpNm_ms\n\nПока планирую выкладывать два видео в неделю, весь список будет [тут](https://goo.gl/yegW0d).\nСпасибо за ваше внимание, и надеюсь, данная информация кому-то будет полезно!\n\n","author":"@Devcolibri","date":"2016-03-02","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"Kotlin Month Post 2: Inheritance and Defaults","url":"https://programmingideaswithjake.wordpress.com/2016/03/05/kotlin-month-post-2-inheritance-and-defaults/","body":"\n## Intro\n\nContinuing on with [Kotlin Month](https://programmingideaswithjake.wordpress.com/kotlin/#kotlinmonth), this week, I’ll be discussing topics in Kotlin that have to do with inheritance and default values.\n\n## Composition Over Inheritance\n\nKotlin has put in a feature and a couple defaults that help developers keep the principle of Composition Over Inheritance at the forefront of their mind. The first of these is a feature that lets you composition almost as easily as inheritance when it comes to defining wrapper classes.\n\n## First-Class Delegation\n\nKotlin provides first-class access to delegation with very little help from you, the developer. All that needs to be done is:\n\n1. The new class inherits from an interface\n1. The new class provides a primary constructor that defines a property that inherits from the same interface\n1. After declaring the inheritance of the interface, include “by ”\n\nFor example:\n\n```kotlin\ninterface A {\n fun doSomething(): Unit\n}\n\nclass B (val a: A) : A by a\n```\n\nIn this example, we have interface `A`, which has a `doSomething()` method to be implemented. Class `B` is our delegator class. It inherits from `A`, includes a primary constructor with a property called `a` that inherits from `A` (`(val a: A)`), and says to delegate to `a` with `A by a`.\n\nNow `B` doesn’t need to explicitly implement any of the methods from `A` because they’re implicitly provided via delegation, just like it would with normal inheritance if `B` was inheriting from a fully implemented class. In this case, instead of just pointing to its parent class implementation, it gets a default implementation as if `B` had been defined like this:\n\n```kotlin\nclass B (val a: A) A {\n override fun doSomething() {\n a.doSomething()\n }\n}\n```\n\nThe delegation can be done for multiple interfaces at a time, too.\n\nI created a [class decorator in Python](https://programmingideaswithjake.wordpress.com/2015/05/23/python-decorator-for-simplifying-delegate-pattern/) that did something like this a while back, since I liked this idea so much.\n\nKotlin practically needed something like this in the language to go along with a certain set of defaults...\n\n## Final By Default\n\nClasses and public methods are `final` by default in Kotlin, meaning they can not be inherited from or overridden, respectively. In order to make those options available, classes and methods must be marked as `open`.\n\nThis goes along with item 17 in Effective Java, namely “Design and document for inheritance or else prohibit it”, just as this entire item lines up with item 16 in Effective Java, “Favor Composition Over Inheritance”.\n\nThese two pieces work together quite nicely and will hopefully mean that code written in Kotlin will be of better quality because of it.\n\nMany people are against the decision of final by default, but they largely seem to not realize that C# has had the same thing all along (without first-class delegation, I might add), and I haven’t heard any complaints from their side. I would venture to guess that most of the people that argue this point also don’t have a mindset of preferring composition. Obviously, there are some cases where this may backfire (especially if a library doesn’t provide an interface for a certain class you want to extend), but this should hopefully prevent more problems than it makes.\n\n## Visibility Modifier Defaults\n\nWhat is the most commonly typed word in all of Java? I would venture to guess that it’s `public`, with `return` and `import` in a close second place. For the most part, that `public` keyword is clutter; most things are public, and it should probably be the default. Kotlin decided to do just that, making the code cleaner.\n\nNow, this does go against the general advice for encapsulation for making members of a class as private as possible, but even when this advice is followed pretty well, `public` is still the most common visibility modifier. So, thankfully, `public` is the default in Kotlin.\n\n## Sealed Classes\n\nSealed Classes are a more interesting than useful feature, in my opinion. They provide a way to lock in a hierarchy so that the only subclasses of the sealed class are those defined within its borders. This is really handy for the split-type monads (such as Either and Maybe/Optional) and, judging by the example used in the documents, expression trees.\n\nAgain, Kotlin has an additional feature that plays well with this feature, and that’s the when expression, which is a reimagined `switch`. The `when` expression is made aware by the compiler to know whether all of the subclasses are presented so that it doesn’t force you to needlessly provide a default `else` clause.\n\nAgain, I find this feature more interesting than useful, especially since I worked out a (slightly more painful) way to largely recreate the same thing in Java (with an additional idea or two running through my head). If you’re curious how I do it, leave a comment letting me know, and I’ll do a post about it.\n\n# Extension Methods\n\nExtension methods are methods that you can “add onto a class” after the fact. I use quotes because they’re not actually added to the class (at least not in Kotlin); rather, they are a static methods that can be used as if they’re methods on an instance, allowing you to import those methods to be used only in certain instances and to discover them with autocompletion. But mostly it’s a syntax that makes static methods look less stupid.\n\nWhy are these not more of a thing in the programming world? All those `String` and `Date` utility classes would be so much easier to use if they could be used as extensions to the actual class. Other than C#, I don’t know of any other languages that do this (understandably, dynamic languages don’t actually need anything special for this feature, since you can literally add any method to a class any time you want). If you know of any, I’d appreciate it if you listed them in the comments.\n\nAnother awesome thing about extension methods is how Kotlin combines them with lambdas to make extension lambdas, which make certain things like [their](https://kotlinlang.org/docs/reference/type-safe-builders.html) [type-safe](https://programmingideaswithjake.wordpress.com/2016/01/16/mimicking-kotlin-builders-in-java-and-python/) [builders](https://programmingideaswithjake.wordpress.com/2016/01/23/kotlin-like-builders-in-java-and-python-continued-additional-parameters/) so much cleaner.\n\n## Outro\n\nThat’s the end of *this* article. Tune in next week for the third post of [Kotlin Month!](https://programmingideaswithjake.wordpress.com/kotlin/#kotlinmonth) That one will go over the safety features that Kotlin has, such as null safety and improved generics.\n","author":"Jacob Zimmerman","date":"2016-03-05","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Write a lightweight, cross-platform HTML5 desktop app with Kotlin","url":"https://medium.com/@lorenzoangelini/write-a-lightweight-cross-platform-html5-desktop-app-with-kotlin-1033eb708800#.rt99y3jm1","body":"\n## How even a developer like me can build stunning cross-platform desktop apps (using Copy & Paste)\n\n#### The problem\n\n**UI design is hard**, very hard, especially for a developer like me.\n\nI love to code, I always think about clever ways to tune and refactor my code.\n\nAt the same time I find building beautiful UIs so hard and frustrating that sometimes I wish I lived when the only way to interact with my app was a lovely black and white command line interface.\n\nBut then, I immediately remember I’ve been lucky enough to live (and code) in years in which **HTML is the glorious standard for web content creation.**\n\nThe best thing that could happen has already happened: **one common presentation “language” shared by everyone**.\n\nThe consequence is that, nowadays, you can find plenty of free online resources for creating stunning HTML5 UIs with little or no effort at all: tutorials, guides and libraries of already-made well-crafted UI widgets are available at your disposal.\n\n**Want to start sketching up a shiny new project but no idea where to start with the UI?** Pick [Bootstrap](http://getbootstrap.com) and you’ll get, immediately, a lot of reusable UI components, already styled by professional designers.\n\nDon’t like Bootstrap default theme? choose [another one](https://bootswatch.com).\n\nDo you want to add some fancy interaction? Pick [React](https://facebook.github.io/react) and you’ll get the framework Facebook developers used for building fast, interactive UIs.\n\n**All well and good until your customer needs a desktop application**: coming from the wonderful world of web development the risk of falling into deep depression becomes real.\n\nIn the world of desktop applications there is neither a common language nor a common technology stack to define user interfaces: billions of programming languages mixed with billions of UI toolkits.\n\n**This heterogeneity of possible solutions leads to less documentation, less examples and most of these solutions aren’t even cross-platform at all**... to sum it up: a complete disaster!\n\nSome solutions have been proposed to overcome this problem: Both the [NW.js](https://nwjs.io/) and the [Electron](http://electron.atom.io) projects let developers write HTML+Javascript code and run it as a desktop app.\n\nThese solutions are really valuable choices (ever heard of the [Atom](https://atom.io/) editor? :)), but, as you may guess, they’re not pure magic and have their own downsides.\n\nActually, your app will be packaged with a shrinked version of the chromium browser to make magic happens... The result? **A simple app built with NW.js/Electron has a size of at least 100MB!**\n\n#### My solution\n\nLuckily enough, it seems that (almost) everyone in this world has a JRE installed on his machine, and even more luckily it seems that JavaFX has a component called WebView that renders HTML5 content.\n\nHoorray! no more need to bundle a browser with my application! :)\n\nSo, **why not mix the power and conciseness of the brand new** [**Kotlin language**](https://kotlinlang.org/) **with all the benefits of HTML5 for UI creation?**\n\nLet’s start now.\n\n#### Your first HTML5 desktop app with Kotlin\n\nWe want to build an extremely simple PhoneBook desktop application.\n\nLet’s start by defining a simple model for our contacts.\n\nWith Kotlin, this task translates to a one-liner, we can use a data class with four attributes: a name, a phone number, an email address and a physical address.\n\nIn the model class, we also add the logic to retrieve data: the “all” function may populate a list of Contacts, fetching data from literaly everywhere (text files, relational DBMS, NoSQL datasources, ...).\n\nFor the purpose of this example project we just create some fake data.\n\n```kotlin\ndata class Contact(val name: String, val phone: String, val email: String, val address: String) {\n companion object {\n fun all() = listOf(Contact(\"Paul Black\", \"+39 334256789\", \"paul.black@example.com\", \"282 Kevin Brook Street, Imogeneborough\"),\n Contact(\"John Red\", \"+44 340556677\", \"john.red@example.com\", \"3316 Arron Smith Drive, New Roads\"),\n Contact(\"Ken White\", \"+32 39876544\", \"ken.white@example.com\", \"169 Ersel Street, Paxtonville\"))\n }\n}\n```\n\nWe now need a function that, given a Contact, returns the HTML markup to render it.\n\nIn this project we will use Bootstrap to make things prettier and every Contact will be displayed inside its “panel”_._\n\nAs you can see, we use Kotlin String interpolation as a sort of template engine.\n\n```kotlin\nfun contactPanel(contact: Contact) =\n\"\"\"\n
    \n

    ${contact.name}

    \n
    \n
    \n
    \n \"${contact.name}\n
    \n
    \n \n \n \n \n \n \n
    Phone: ${contact.phone}
    Email: ${contact.email}
    Address: ${contact.address}
    \n
    \n
    \n
    \n
    \n\"\"\"\n```\n\nMaking use of the above function, we should now build another function that, given a Contact list, returns the complete HTML view.\n\n```kotlin\nfun contactsView(contacts: List) =\n\"\"\"\n\n \n \n \n My contacts\n \n \n
    \n
    \n
    \n ${contacts.map { contactPanel(it) }.joinToString(\"\\n\")}\n
    \n
    \n
    \n \n\n\"\"\"\n```\n\nAs you may have already spotted in the HTML template, we need references to other static files such as images, css and javascript resources.\n\nWe use an helper method called “resourceLink” that solves this problem for us.\n\nLet’s build this method into the class that is responsible to handle the window and Webview creation.\n\nIt’s really simple and takes advantage of the [Java resource system](http://docs.oracle.com/javase/7/docs/technotes/guides/lang/resources.html) to access static files that will be bundled inside the final executable Jar of our app.\n\n```kotlin\nfun resourceLink(path: String) = \"${HTML5View::class.java.getResource(path)}\"\n```\n\nIt’s time to take a look at the class that creates the JavaFX window and the WebView that will render our HTML and execute our Javascript code.\n\nUsing [TornadoFX](https://github.com/edvin/tornadofx), a lightweight JavaFX framework for Kotlin, building this class becomes really simple and natural: TornadoFX uses several language features from Kotlin to create JavaFX visual components with the most concise code as possible.\n\n```kotlin\nclass HTML5View : View() {\n companion object {\n fun resourceLink(path: String) = \"${HTML5View::class.java.getResource(path)}\"\n }\n\n override val root = WebView()\n init {\n with(root) {\n setPrefSize(800.0, 600.0)\n // Atomatically set the title of the window as the HTML document title\n titleProperty.bind(engine.titleProperty())\n // Show all the contacts\n engine.loadContent(contactsView(Contact.all()))\n }\n }\n}\n```\n\nThe last thing left to do is to create the “main” function that starts our application.\n\n```kotlin\nclass HTML5App : App(HTML5View::class)\n\nfun main(args: Array) = Application.launch(HTML5App::class.java)\n```\n\nAnd that’s all the code needed for this simple PhoneBook application... Pretty easy right? :)\n\nWe can now use the “shadowJar” Gradle plugin to package a redistributable fat executable Jar with all the dependencies, and it weights only 4.6 MB!\n\n![](https://cdn-images-1.medium.com/max/800/1*dJiZHivKunYuYpSI5NZfpg.png)\n\nStarting form this example project, **it’s easy to extend this idea and build beautiful, lightweight and cross-platform applications** taking advantage of all the resources the web has to offer for creating HTML content.\n\nYou can find all the complete source code at [my Github account](https://github.com/lorenzo-ange).\n\n[**lorenzo-ange/html5-desktop-app**](https://github.com/lorenzo-ange/html5-desktop-app) - _This is an example of a desktop application written with Kotlin and HTML5._\n\n**Thanks for reading!**\n\n","author":"Lorenzo Angelini","date":"2016-12-24","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.0.3 EAP","url":"https://discuss.kotlinlang.org/t/kotlin-1-0-3-eap/1729","body":"\nWe're starting Kotlin `1.0.3` EAP.\n\n### What's new\n\n1.0.3 brings some minor changes to compiler and lots of improvements to IntelliJ plugin:\n- Improved completion, refactorings, Maven support, formatter and Spring support\n- Language injection support\n- New intentions, inspections and quickfixes\n- Lots of bugfixes\n\nSee full [changelog](https://github.com/JetBrains/kotlin/blob/3731e170e459bf02b562464ca02ccb6812760ee2/ChangeLog.md)\n\n### How to get EAP build\n\nTo use this build from Gradle or Maven, add [https://dl.bintray.com/kotlin/kotlin-eap](https://dl.bintray.com/kotlin/kotlin-eap) to your repositories.\nTo use the new version of the Kotlin plugin for IntelliJ IDEA, configure Early Access Preview channel in **Tools | Kotlin | Configure Kotlin Plugin Updates** and press \"Check for updates now\".\n\nBuild number is `1.0.3-eap-30`\n\nPlease do provide feedback and report any issues to our [issue tracker](https://youtrack.jetbrains.com/issues/KT#newissue) (please specify your plugin version and IDE version)\n\n","author":"Pavel Talanov","date":"2016-06-08","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Announcing the Support Program for Kotlin User Groups and Events","url":"https://blog.jetbrains.com/kotlin/2017/01/announcing-the-support-program-for-kotlin-user-groups-and-events/","body":"\nToday we are launching a new [Community section at our web-site](https://kotlinlang.org/community/)!\n\n![Explore Kotlin Community](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2017/01/Screen-Shot-2017-01-26-at-17.37.05.png)\n\nIt will provide you with the guidelines to organize Kotlin related events, and the description of support managed by JetBrains. We are now happy to announce that we have formalized the support process for User Groups and Events around Kotlin.\n\nIt is exciting to see that in 2016 about 150,000 of developers all over the world tried Kotlin. We now have an amazing community, which enables us to hold Kotlin-dedicated talks and meetups. We have also held two Kotlin Nights: the first one [was in San-Francisco](https://blog.jetbrains.com/kotlin/2016/06/kotlin-night-recordings/) and the other one [was in London](https://blog.jetbrains.com/kotlin/2016/09/kotlin-night-in-london/). What is even more fantastic is that you, the community, start to organise these events, and we are here to help. It is also great to see demand for more Kotlin Nights.\n\nWe offer the following programs:\n\n## [Kotlin User Groups Support Program](https://kotlinlang.org/community/user-groups.html)\n\nWe appreciate what you do and would love to help you find partners and speakers for your meetups, as well as to help promote your events. We can give you swag and provide you with an advice. Please [fill up the form for your user group](https://docs.google.com/forms/d/e/1FAIpQLSdkLbD_SPbXZDVW2nQPgUiLCW4HOSXysOVK1jPLcShPfyhkNA/viewform) or feel free to reach out via [e-mail](mailto:alina@jetbrains.com).\n\n## [Kotlin Nights Support Program](https://kotlinlang.org/community/kotlin-nights.html)\n\nWe encourage everyone who wants to organise a Kotlin Nights event to do so. We can provide support in terms of merchandise, and promote your event via our media channels. We have a Kotlin Night Kit available for you to use, which includes the guidelines, branding materials and swag for speakers and attendees. If you need help reaching out to potential partners or with any other steps, feel free to ping us via [e-mail](mailto:alina@jetbrains.com).\n\n## [Kotlin Talks & Speakers Support](https://kotlinlang.org/community/talks.html)\n\nIf you are a speaker, let us know about your upcoming event, and we will send you a t-shirt and stickers for the attendees. By the way, they are available online for everyone at [Stickermule](https://www.stickermule.com/user/1069238064/stickers) and [Apparel Store](https://www.ptxstore.com/jetbrains/product_info.php?products_id=3011). Check out the New Events web page and [submit your talk](https://docs.google.com/forms/d/e/1FAIpQLSfeXstxUcBsOypWtE9McIpYU82szB3yIYkU-30fNXOVoJocEQ/viewform) to show up on the global [Kotlin activities map](https://kotlinlang.org/community/talks.html).\n\nJUGs and GDGs are also encouraged to participate! If you have Kotlin-related talks or specially dedicated meetups, [submit them](https://docs.google.com/forms/d/e/1FAIpQLSfeXstxUcBsOypWtE9McIpYU82szB3yIYkU-30fNXOVoJocEQ/viewform), and we will figure out an optimal support plan for you.\n\nMoreover, we have a standard JetBrains Community Support Program for user groups related to software development , as well as community-driven events, not just Kotlin-related. [You can easily apply here](https://www.jetbrains.com/support/community/?fromMenu#section=communities).\n\nIf you have any questions, please ping [Alina](mailto:alina@jetbrains.com), who will be more than happy to help you.\n","author":"Alina Dolgikh","date":"2017-01-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Погружение в Async-Await в Android","url":"https://habrahabr.ru/post/314656/","body":"\n\n","author":"Макс Ровкин","date":"2016-11-09","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"How to get IDEA to detect kotlin generated sources using Gradle","url":"https://blog.nishtahir.com/2016/06/25/how-to-get-idea-to-detect-kotlin-generated-sources-using-gradle/","body":"\nSo I recently got my hands on Kotlin and it's been great so far.\n\nHowever one of the things that the IDEA kotlin plugin doesn't do[1](#fn:1) is detect the `kapt` folder which contains any sources generated from annotation processing. This can be fixed using the IDEA gradle plugin[2](#fn:2).\n\nThe idea plugin isn't able to mark the kapt folder as a source directory unless it's been added to the gradle source set.\n\n```gradle\nsourceSets.main.java.srcDir file(\"$buildDir/generated/source/kapt/\")\n\n```\n\nThe next step is to tell the idea plugin to mark the kapt folder as a generated sources root in the module[3](#fn:3).\n\n```gradle\nidea { \n module {\n // Tell idea to mark the folder as generated sources\n generatedSourceDirs += file(\"$buildDir/generated/source/kapt/\")\n }\n}\n```\n\nWhen put together your build script should look a little like this.\n\n```gradle\napply plugin: 'idea'\n\n...\n\nkapt { \n generateStubs = true\n}\n\n// Add kapt directory to sources\nsourceSets.main.java.srcDir file(\"$buildDir/generated/source/kapt/\")\n\nidea { \n module {\n// Tell idea to mark the folder as generated sources\n generatedSourceDirs += file(\"$buildDir/generated/source/kapt/\")\n }\n}\n```\n\n###### Footnotes and references\n\n1. →, V. (2015). Better Annotation Processing: Supporting Stubs in kapt. [online] Kotlin Blog. Available at: [https://blog.jetbrains.com/kotlin/2015/06/better-annotation-processing-supporting-stubs-in-kapt/#comment-36065](https://blog.jetbrains.com/kotlin/2015/06/better-annotation-processing-supporting-stubs-in-kapt/#comment-36065) [Accessed 25 Jun. 2016]. [↩](#fnref:1 \"return to article\")\n\n2. Docs.gradle.org. (2016). The IDEA Plugin - Gradle User Guide Version 2.14. [online] Available at: [https://docs.gradle.org/current/userguide/idea_plugin.html](https://docs.gradle.org/current/userguide/idea_plugin.html) [Accessed 25 Jun. 2016]. [↩](#fnref:2 \"return to article\")\n\n3. Docs.gradle.org. (2016). IdeaModule - Gradle DSL Version 2.14. [online] Available at: [https://docs.gradle.org/current/dsl/org.gradle.plugins.ide.idea.model.IdeaModule.html](https://docs.gradle.org/current/dsl/org.gradle.plugins.ide.idea.model.IdeaModule.html) [Accessed 25 Jun. 2016]. [↩](#fnref:3 \"return to article\")\n","author":"Nish Tahir","date":"2016-06-25","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Eclipse Plugin 0.7 Is Here!","url":"http://blog.jetbrains.com/kotlin/2016/06/kotlin-eclipse-plugin-0-7-is-here/","body":"\nWe are happy to present a new release of our plugin for Eclipse IDE. Along with the support for Kotlin **1.0.2** compiler, this update brings very important features and improvements.\n\nThe code formatting feature was rebuilt in this release. Instead of our first naive implementation we have mostly managed to port the advanced formatter from the Kotlin IntelliJ Idea plugin into Eclipse. This means that [a lot of fixes](https://youtrack.jetbrains.com/issues/KT?q=Formatter%20State:%20Fixed%20Subsystems:%20IDE) are already there and upcoming improvements will be picked up automatically!\n\n![](http://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/fromater.gif)\n\nNew line auto-indent also benefitted from this code reuse and now shows far more predictable and smart behaviour.\n\nIt was possible to add missing classes imports one-by-one with a quick-fix since 0.1.0 version, and now we’ve improved on that by introducing the _Organize Imports_ feature. It will clean unused imports, add missing imports for classes used in the file and resort them.\n\n![](http://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/organize.gif)\n\nOur completion got several fixes in prioritizing variants and is now far more usable. Also not-imported classes are now suggested in completion popup at once and will be inserted together with the corresponding import.\n\n![](http://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/import.gif)\n\nSeveral quick-fixes about missing or illegal modifiers were added:\n\n* It’s now possible to add an open modifier to a declaration which is overridden or subclassed.\n ![](http://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/open.gif)\n* It’s now easy to deal with the _“class must be declared abstract”_ compiler error.\n ![](http://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/abstract.png)\n\n* Invalid modifier removing is now also available from the quick-fix popup.\n ![](http://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/modifiers.png)\n\nPlease give it a try.\n\n[![Drag to your running Eclipse workspace to install Kotlin Plugin for Eclipse](http://i2.wp.com/marketplace.eclipse.org/sites/all/themes/solstice/_themes/solstice_marketplace/public/images/btn-install.png?zoom=1.5&w=640)](http://marketplace.eclipse.org/marketplace-client-intro?mpc_install=2257536 \"Drag to your running Eclipse workspace to install Kotlin Plugin for Eclipse\")\n\nIf you run into any problems or encounter missing features, please don’t hesitate to leave your feedback here or file issues in YouTrack.\n\n","author":"Nikolay Krasko","date":"2016-06-03","type":"article","categories":["Kotlin","Eclipse"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Experimenting with “mutation testing” and Kotlin","url":"https://medium.com/@s4n1ty/experimenting-with-mutation-testing-and-kotlin-b515d77e85b5#.9ps78uqer","body":"\nThe most common approach to measuring how comprehensive your unit tests are is to look at “code coverage”, literally the number of lines of your code that are executed by your unit tests.\n\nWhile this isn’t a bad approach, it really only tests what code is executed by your tests, it doesn’t directly measure their ability to detect bugs in your code, which is their purpose. You could easily write unit tests that execute every line of code, and yet will pass regardless of what your code actually does.\n\nMutation testing addresses this problem. In a completely automated way, it deliberately introduce bugs (“mutations”) in your code, and then verifies that the unit tests fail.\n\nThere is an excellent tool called [Pitest](http://pitest.org/) for Java and other JVM languages that does exactly this, so I decided to test it on a relatively [simple library](https://github.com/sanity/pairAdjacentViolators) I created recently (related to machine learning), I did my best to unit test it fairly comprehensively.\n\nMy library is implemented in [Kotlin](http://kotlinlang.org/) (which runs on the JVM) and which uses Gradle as a build tool. Adding Pitest was super-easy, I expected some headaches because I’m using Kotlin and not Java, but it worked perfectly first time, exactly as advertised. Very impressive. [Here](https://github.com/sanity/pairAdjacentViolators/commit/38abd1edfdb4389fee4a31be867dfd4c29747a36) are the modifications required to my build.gradle file.\n\nPitest took between 17 and 30 seconds to run, quite fast considering. Pitest appears to be fairly smart about only running the unit tests that matter for any given file, which suggest that it will scale linearly with the size of your codebase.\n\n[Here](https://sanity.github.io/pairAdjacentViolators/pitest-example/) are the results. They look very similar to a normal code coverage report, you can see each of the three main classes in the project, and if you click on each you can see the respective source file, with each line of code colored red or green.\n\nTake line 17 of [PairAdjacentViolators.kt](https://sanity.github.io/pairAdjacentViolators/pitest-example/PairAdjacentViolators.kt.html), if you mouseover the ‘1’ to the left of the code you can see that here it attempted a mutation, specifically changing:\n\n```kotlin\nval combinedWeight = weight + other.weight\n```\n\nto..\n\n```kotlin\nval combinedWeight = weight - other.weight\n```\n\nAnd, as we would hope, this resulted in a “kill”, a unit test failure.\n\nNow let’s look at line 39, which is marked red:\n\n```kotlin\nPAVMode.INCREASING -> previous.y >= next.y\n```\n\nIf you mouseover this you can see that reversing the condition (>= becomes <=) did result in a failure, but simply changing the conditional boundary (from >= to >) did not. This is unsurprising as this is a very subtle change, but impressive that it was caught.\n\nEvery instance where a code mutation doesn’t result in a unit test failure prompts an interesting train of thought about why not. Is it because the code is unimportant (like a toString() method only really used for debugging)? Is it because the change is too subtle and the difference in code behavior is unimportant? Or is it something that should really have been tested? This is a very healthy thought process if you really care about the correctness of your code.\n\nIf I was working on code where I needed a very high degree of reliability, I think mutation coverage is an excellent way to ensure that your unit tests are effective, and at pointing out areas where they might require further work.\n\n","author":"Ian Clarke","date":"2016-10-16","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Code Swarm for Kotlin","url":"https://www.youtube.com/watch?v=UTN2_YXEzL4","body":"\n\n\n\ncode_swarm visualization for kotlin (https://github.com/JetBrains/kotlin). The Kotlin Programming Language\n\nThis visualization was generated by following this tutorial:\nhttp://derwiki.tumblr.com/post/43181171352/creating-a-codeswarm-for-your-git-repository\n\nMore information:\nhttp://vis.cs.ucdavis.edu/~ogawa/codeswarm/\nhttps://github.com/rictic/code_swarm\n\nWhy make this visualization?\n- I'm studying how popular projects evolve\n\n","author":"Landon Wilkins","date":"2016-11-24","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin’s Android Roadmap","url":"http://blog.jetbrains.com/kotlin/2016/03/kotlins-android-roadmap/","body":"\n## Introduction\n\nOne of the most interesting pieces of news we’ve all seen recently is Google announcing [(limited) Java 8 support for Android N](http://developer.android.com/preview/j8-jack.html) with the Jack compiler for Java. Naturally, our users are curious about how these news affect them, and this blog post outlines our plans and our vision for Kotlin’s place in the Android development world in light of Google’s announcements.\n\n### Kotlin’s Roadmap for Android\n\nWe pay a lot of attention to making Kotlin a good tool for Android development. In the next few releases (1.0.X) we will continue improving our toolchain and libraries. Our current efforts are focused on three main areas: speeding up the development workflow, reducing the size of the runtime library and providing more complete tooling support.\n\n#### Development Workflow\n\nTo speed up the development workflow, **incremental compilation** is coming to Kotlin’s Gradle plugin. This will improve the build times considerably: when a source file is changed, we’ll only recompile this particular file and those files really depending on it, not the whole module.\n\nThe next thing we plan to do to improve Android build performance is providing an integration with Android’s new **[Jack and Jill toolchain](http://tools.android.com/tech-docs/jackandjill)**. Right now there are some issues that prevent Jack from handling Kotlin-generated bytecode correctly ([196084](https://code.google.com/p/android/issues/detail?id=196084) and [203531](https://code.google.com/p/android/issues/detail?id=203531)), but we plan to work together with the Google team to either resolve the issues or provide workarounds on our side. Once this is done, we’ll be able to translate only changed class files using Jill during incremental compilation, as opposed to translating all class files every time (which is the only possible behavior in the old Android tooling).\n\nLast, but not least: **Instant Run**. Currently, Cold Swap works fine for Kotlin, but Warm and Hot Swap require some further investigation. We’ll do what we can to get them fixed ASAP. In the meantime, [JRebel for Android](https://zeroturnaround.com/software/jrebel-for-android/) works fine with Kotlin already.\n\n#### Runtime Size\n\nWe are planning several improvements to **reduce the methods count** of kotlin-stdlib. Our current result is 7’191: ![http://www.methodscount.com/?lib=org.jetbrains.kotlin%3Akotlin-stdlib%3A1.0.0](https://img.shields.io/badge/Methods%20count-core:%206289%20|%20deps:%20902-e91e63.svg)\n\nOptimizing top-level functions representation in multi-file facade classes and moving inline-only functions out of the runtime-available binary will win us several thousand methods.\n\n#### Tooling Support\n\nThe main thing missing from Kotlin 1.0’s Android support story is **Lint Checks**, and we’re happy to announce that they are coming to Kotlin. We have already implemented all the checks available in Android Studio 1.5 (planning to publish them in Kotlin 1.0.2), and the new 2.0 checks are on the way. Our Lint checks are built on top of a common representation of Kotlin and Java code, and we plan to contribute that representation to the Android SDK, so that new checks added in future versions of the Android SDK will work with Kotlin out of the box.\n\nMore Android-specific IDE support, such as a _New Kotlin Activity_ action, code insight and navigation features, and others will also be added gradually as 1.0.X releases are published.\n\n### Kotlin and Java 8\n\nJava 8 has been around for quite a while now, and thus many of our users, those who are not doing Android development, have chosen Kotlin over Java 8 and are happy about it. Now that Android has official support for the Java 8 language features, how does that change the decision of choosing between Kotlin and Java?\n\nFirst of all, while Java 8 does bring lambdas to Android, there are important differences between the way the Android toolchain supports lambdas on existing platform versions (that don’t run the N release) and the way Kotlin supports lambdas. To understand the difference, let’s see how the following simple code snippets are compiled:\n\nKotlin: `list.forEach { process(it) }`\nJava 8: `list.forEach(it -> process(it))`\n\nJava’s version is a tiny bit longer, but let’s not focus on that. Instead, let’s see what happens under the hood. Starting with Java:\n\n* in Android’s Java 8 every lambda is compiled to a class, which has two methods: constructor and the actual body (affecting the method count of your application);\n* this class is later instantiated at runtime, in many cases — every time the `forEach` is called (creating pressure on the garbage collector);\n* and to access it, Java uses a polymorphic call to `Consumer.accept`, which may happen on every iteration in a tight loop (affecting performance, because the runtime cannot always inline such calls).\n\nKotlin, on the other hand, supports inline functions, and `forEach` is one such function. When you use an inline function with a lambda, both the body of the function and the lambda are inlined at the call site. As a result:\n\n* the bytecode of the lambda is inserted directly into the bytecode of the calling method, so the method count does not increase;\n* executing the code does not allocate any objects, so there is no garbage collector pressure;\n* the resulting bytecode does not contain any polymorphic method calls, ensuring the best possible execution speed at runtime.\n\nBottomline: lambdas in Java 8 on Android are not at all free, and one should probably think twice every time and choose between good code and performance. In Kotlin, you don’t have to make such compromises, and you can use lambdas as much as you need to express the ideas in your code.\n\nAnd of course, Kotlin has many other language features which are not available in any version of Java. Just to list a few:\n\n* Support for **null-safety** prevents most of the NullPointerException problems in your code, saving you from the dreaded “Unfortunately, application has stopped” message;\n* **Properties, primary constructors and data classes** greatly reduce the amount of boilerplate in the code representing the data model of your application:\n `data class User(val name: String, val groupId: String = \"default\")`\n* **Delegated properties** allow to extract the common logic in property getters and setters and to put that into a library:\n `val imageData by lazy { loadData(imageFile) }`\n\nAnd the DSL construction features of Kotlin give you an entirely new level of flexibility in building your application which is simply not available in Java. For example, it gives you the option to replace XML layouts with an embedded DSL and to describe the UI of your application in the same language as the rest of the code, with full access to the abstraction features of the language. Here’s how this can be accomplished using the [Anko library](https://github.com/kotlin/anko):\n\n```kotlin\nverticalLayout {\n val name = editText()\n button(\"Say Hello\") {\n onClick { toast(\"Hello, ${name.text}!\") }\n }\n}\n```\n\nAs you see, Kotlin has lots and lots of things to offer to make you more productive, beyond what Java 8 can offer to a Java 6 developer. And it’s also easy to learn, with [comprehensive documentation](https://kotlinlang.org/docs/reference/), [interactive exercises](http://blog.jetbrains.com/kotlin/2016/03/kotlin-educational-plugin/) and books covering both [Kotlin in general](https://www.manning.com/books/kotlin-in-action) and the use of [Kotlin for Android development](https://leanpub.com/kotlin-for-android-developers). So if you haven’t tried Kotlin yet, now is as good time as any!\n\n","author":"Dmitry Jemerov","date":"2016-03-30","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"GeeCON Prague 2014: Andrey Cheptsov - A Reactive and Type-safe Kotlin DSL for NoSQL and SQL","url":"https://vimeo.com/110781020","body":"\n[GeeCON Prague 2014: Andrey Cheptsov - A Reactive and Type-safe Kotlin DSL for NoSQL and SQL](https://vimeo.com/110781020)\n\n","author":"Andrey Cheptsov","date":"2014-11-03","type":"video","categories":["Kotlin","SQL"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin: как сделать жизнь Java-разработчика легче?","url":"https://dev.by/lenta/anadea/kotlin-kak-sdelat-zhizn-java-razrabotchika-legche","body":"\n15 февраля 2016 года компания JetBrains выпустила версию 1.0 языка Kotlin, находившегося в разработке около пяти лет. Работает этот язык поверх JVM. Что такое Java, мы уже рассмотрели в отдельной статье с Александром Михальченко. Сегодня мы снова собрались с ним, на этот раз для разговора о Kotlin - о том, чем хорош этот язык и чем плох, как для разработчиков, так и для предпринимателей.\n\n**Привет, Саш.** \n\nИ тебе привет.\n\n**Итак, что, собственно, такое Kotlin?** \n\nЯзык программирования, разработанный компанией JetBrains, работающий на платформе Java. Он использует JDK, как и сама Java, но имеет другой синтаксис. Решение не ново - уже существуют языки, которые так делают: Scala и Closure, например. Появились они, в основном, из-за проблем с самой Java в плане синтаксиса. То есть, Java - язык надежный, хороший, добротный, на нём можно писать серверные приложения, но синтаксис у него, скажем так, излишне многословный. Дело в том, что разработчики Java довольно инертно её дорабатывают. Они стараются по максимуму поддерживать обратную совместимость и считают, что у пользователей, перешедших на новую версию, должен работать код, написанный ещё в 95-м. У них даже лозунг такой: \"написанное однажды работает везде\". Это, конечно, больше про кроссплатформенность...\n\n**...но они решили копнуть глубже?**\n\nДа - написано на одной версии, будет работать на всех следующих.\n\n**Смело!**\n\nВ этом, собственно, и заключается проблема - ничего старого из языка они не выкидывают. Из-за этого замедляется его развитие. Со временем появляется всевозможный мусор. Там даже есть метка для устаревших классов, которая стоит над ними внутри самого JDK. В документации, конечно, говорится, что если такая метка появилась, то в одной из следующих версий устаревшая функциональность может исчезнуть, но мне такие случаи неизвестны.\n\n**Сами разработчики понимают, что эти устаревшие методы уже давным-давно никто не использует?**\n\nОни понимают и даже настаивают на том, чтобы эти методы не использовали. Но поскольку есть софт, написанный на старых версиях, не получится так просто убрать старый код. Всё те приложения сломаются.\n\n**От чего же избавился Kotlin?** \n\nKotlin и другие JVM-языки помогли разработчикам писать программы с меньшим количеством кода. Помимо всего того, что есть в Java, они добавляют вещи из мира функционального программирования. Это значительно облегчает написание кода - делает его короче и выразительнее. Чем меньше кода мы пишем, тем меньше кода нужно поддерживать, писать меньше тестов. Собственно, большинство языков появилось по этой самой причине - поменять синтаксис Java, сделать его более удобным, более прагматичным.\n\n**Насколько сейчас актуален этот язык?** \n\nСейчас он не то, чтобы слишком популярен - язык молодой, сообщество ещё не набралось. По причине своей молодости Kotlin ещё не в силах конкурировать с той же Scala - более мощным языком с длинной историей. Там уже и над ошибками поработали, и добавили кучу интересных вещей, а Kotlin это только предстоит. В этом более зрелые языки пока что его переигрывают. Но тем не менее, амбиций Kotlin не занимать: язык разрабатывали пять лет, разработчики старались сделать его как можно прагматичнее и не допустить ошибок, которые есть в Java, чтобы \"написано однажды\" не было высечено в камне и язык можно было развивать. Обещают много интересных фич в будущем, которые в том числе покроют функциональность, имеющуюся на данный момент в Scala.\n\n**Как и Java, Kotlin лучше подойдёт большим проектам?** \n\nДа. По синтаксису, его можно использовать просто как дополнение к Java. Берём стек Java, к примеру, для серверных приложений, и просто заменяем Java на Kotlin. Всё будет работать, при этом, писать код станет проще. Вопрос заключается лишь в том, что выбрать вместо Java. На сегодняшний день, думаю, многие разработчики всё же остановятся на Scala.\n\n**А тебе что больше по душе - Kotlin или Scala?** \n\nМне нравятся оба языка. Думаю, что Kotlin дальше пойдёт в плане Android. Есть, конечно, возможность писать Android-приложения на Scala, но там есть проблема: большой runtime. Она за собой тащит кучу библиотек, из-за чего увеличивается размер apk-файла. У Kotlin же самый маленький runtime среди всех остальных языков (кроме Java). Обычно это Java плюс \"что-то\", и это \"что-то\" - это overhead, который за собой язык тащит. У Kotlin он самый маленький - около 700 кб, в то время как у Scala - несколько мегабайт.\n\n**Какие недостатки у Kotlin?** \n\nСам я пока что не натыкался ни на какие баги, с компилятором или чем-то другим у меня проблем тоже не было. По поводу синтаксиса - он справлялся с задачами, с которыми я сталкивался. В чём он уступает той же Scala - это в работе с многопоточностью. Java, к слову, тоже в этом проигрывает. У Scala есть future API, которая позволяет выполнять асинхронные задачи в несколько потоков и при этом получается нормальный код вместо мешанины, где разные секции работают в разных потоках и при этом не видна их связь. Scala всё это структурирует средствами своего синтаксиса. В Kotlin что-то такое обещали реализовать в версии 1.1. Но в целом, мне нравится работать на Kotlin из-за его добротного синтаксиса.\n\n**Что скажешь насчёт безопасности Kotlin?** \n\nТут вот в чём дело: весь код, написанный на Kotlin, в дальнейшем преобразуется в Java-код. Своего он ничего не добавляет. Соответственно, насколько безопасна Java, настолько безопасен и Kotlin. Если мы говорим о безопасности написания кода, то мне очень нравится null safety в Kotlin. Компилятор может предупредить программиста о том, что ссылка может быть пустой. Если мы попробуем с ней что-то сделать, произойдет ошибка на этапе компиляции. В Java же приложение просто упадет на этапе выполнения.\n\n**Что Kotlin может предложить бизнесу? Чем он заинтересует бизнесменов?** \n\nЕсли сравнивать с Java то разработка на Kotlin обойдётся дешевле. Почему? Нужно писать меньше кода и меньше кода поддерживать. Это значит, что код писать проще, а следовательно, приложение будет разрабатываться быстрее. А как известно, время - это деньги.\n\n**Маленькие проекты и Kotlin.** \n\nЕсли мы говорим о каких-то маленьких десктопных приложениях, то для коммерческого использования лучше брать С++. Опять же, Kotlin в дальнейшем транслируется в Java, поэтому, насколько Java хороша в какой-то области, настолько хорош и Kotlin. Kotlin больше помогает писать программы, непосредственную пользу он приносит в первую очередь программистам.\n\n**Спасибо большое за интервью, Саш. Было интересно!**\n\nВсегда рад.\n\n**Итого**\n\nПо сути, прямое назначение Kotlin - облегчить жизнь программистов, дать им возможность уместить в одну строчку кода то, что в Java заняло бы пять. Как сказал Александр, по ощущениям это сродни смене старого Ford Focus на новенький BMW M3 - когда почувствуешь этот полёт, на старые колёса не захочется возвращаться.\n\nНесомненным преимуществом является полная совместимость с Java, в том числе и обратная. Все библиотеки для Java будут работать на Kotlin и наоборот. Также этот язык открывает прелести тех же Closure и Scala для Android-разработчиков. Порадуются и предприниматели, ведь теперь проекты будут делаться быстрее и дешевле.\n\nМинус у языка один - его юный возраст. Однако, судя по тому, что JetBrains целых пять лет потратили на его разработку, очень сомнительно, что они забросят своё детище в ближайшие годы. Поэтому уже сейчас можно и нужно брать Kotlin на вооружение - тем более, если вы разрабатываете приложения для Android.\n\n","author":"Stanislav Sinitsky, Alexander Mikhalchenko","date":"2016-12-07","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"More readable tests with Kotlin","url":"http://tengio.com/blog/more-readable-tests-with-kotlin/","body":"\n# More readable tests with Kotlin\n\n_The following is a highly opinionated rant. These are just my personal views on a subject I care about._\n\nTests should be easy to read. You should be able to go to a test class you are not familiar with, collapse all the methods, and have a very quick read of all the test names. You do that, and in a matter of seconds you should have a very good idea of what the system under test is expected to do and in what circumstances. If you can do this then what they say about tests, that they serve as living documentation, becomes more true than ever.\n\nNow here’s what a BDD-style `given-when-then` format I’ve seen used and have used myself in the past looks like:\n\n![article-img](http://tengio.com/img/blog/0002/given-when-then-sample.jpg) _Given when then tests_\n\nIt’s not exactly a pleasure to read a screen full of this stuff is it? The `given-when-then` keywords take up precious space on the screen. I really don’t want to read a screen full of this stuff, because after a while it sort of starts looking a bit like:\n\n```kotlin\n@Test\nfun blahblahIHopeTheyPayMeThisMonthBlahblahBlahblahBlahblah() { ... }\n\n@Test\nfun blahblahBlahblahIHateMyLifeBlahblahBlahblahBlahblahBlahBlahBlah() { ... }\n\n@Test\nfun blahblahBlahblahBlahblahBlahIWantToGoHomeAndCryBlahblahBlahBlahBlah() { ... }\n```\n\nat which point I might well be tempted to uncollapse the methods and just read the test code, and bam! my reading speed and information retention just plummeted. Not what I wanted.\n\nWell, that’s one way of doing it, but there are others. Roy Osherove suggests something like the following format instead:\n\n```kotlin\n@Test\nfun createUser_WithAllFieldsValid_DisplaysSuccessScreen() { ... }\n\n@Test\nfun createUser_WithAnyInvalidField_DoesNotSendRequest() { ... }\n```\n\nI’ve used that for a while, it was neat and I liked it. It still has a clear structure, and it gets rid of the formulaic keywords `given-when-then` while achieving a very similar result. Nice, but in my humble opinion it still has a little bit of a flaw. It reads like it was meant to be read by a robot, not a human. Also it’s pretty much inevitable that eventually you run on problems expressing your intention behind what you are trying to test when using this format. Or maybe it’s just me.\n\nSo here’s an alternative approach I prefer using at the moment, which I think I learnt from [@mvarnagiris](https://medium.com/@mvarnagiris) :\n\n```kotlin\n@Test\nfun displaysSuccessScreenWhenCreatingAUserWithAllFieldsValid() { ... }\n\n@Test\nfun doesNotSendRequestWhenCreatingAUserWithAnyFieldInvalid() { ... }\n```\n\nI think it reads more like what you would actually say when asked “what does this system do?” by a colleague or manager. You lose the nice structure of the other formats, but hey, I don’t see many people explaining their product owner or colleague what they just did by speaking like a robot.\n\nBut wait what’s that? Oh look! It’s the good old `blahblahBlahblahBlahblahIsIt530YetBlahblahBlahblah()` effect again!\n\nNow, it’s Kotlin we’re using, so let’s use the `` thingy Kotlin offers, I say. Feel free to use them in your test methods, or even class names, and feel free to write your test names in a as readable and as descriptive a way as you can. This is what I’d rather see:\n\n![article-img](http://tengio.com/img/blog/0002/human-readable-tests.jpg) _Human readable tests_\n\nNow I can read a whole page of this stuff, quickly and without getting tired. What’s more, I can actually read the summaries of the tests that have run at the bottom of the screen and actually get some more info out of it more than that all my `givenBlahblahCoolStoryBroBlahblah`s are green, whatever they mean. What summary would you rather read?\n\n_Wall of text meant for robots:_\n\n![article-img-not-scaled](http://tengio.com/img/blog/0002/robot-readable-results.jpg)\n\n_Information meant for humans:_\n\n![article-img-not-scaled](http://tengio.com/img/blog/0002/human-readable-results.jpg)\n\nI for one would definitely go for the second one. But that’s only my fallible opinion anyway, what do _YOU_ think?\nn\n\n","author":"Flavio","date":"2016-08-05","type":"article","categories":["Kotlin","Tests"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Thinking Functionally","url":"https://medium.com/lewisrhine/thinking-functionally-7149814df9b9#.1vlgn9qm1","body":"\nOne of the great things happening right now in software development is the blending of functional and Object Ordained ideas. While things like Scala have been doing this for a while now, the explosion of popularity of things like Kotlin, Swift, and Rx are giving developers the best of both worlds. Hell, even JavaSript now has classes (I know JS lovers, classes are the devil).\n\nThe problem is that the benefits of functional practices don’t easily jump out to people. If you have taught in OOP your entire professional life it’s going to be hard to change. It is completely valid to see the benefits and not think it’s worth it, but if you don’t completely understand what the real benefits are you can’t make an educated decision.\n\nThe best example of this is is the Android world right now is Rx. This is a question that comes up a lot with Rx, “Yeah but... does it need to be a stream?” It’s a really important question. It’s like a levee breaking the relentless waves of “Use Rx! Rx everything!” For me, it’s also a mark of the failings of communication on the pro-Rx side.\n\nRx is all about reactive functional programming but the reactive part gets all the attention. It leads to a lot of misunderstanding, misuse, and mistrust of Rx. When you’re getting a list of items why not just return a list? Why would you need to return it as a stream? If you are told to look at Rx as reactive streams only, it’s easy to say you don’t need a stream. Just get the list.\n\nThe problem is that this leads to thinking of the list as an object with state, not just data. There is a good chance that once you get the list you are going to just pass it around to other classes. If one of them needs to sort or filter the list you are going to just call those methods on the object and change its state. But what about the other classes using it? They are expecting that list to be in a different state. Before you know it you have an out of control state.\n\nHowever, if you think of it as a stream of data that you can run through a series of functions you can start to frame the true benefits. If you need to sort or filter the data instead of modifying the state of an object, ask for the data stream again this time running through a sort, or filter function. You are not just making that list a stream for the sake of making it a stream. You are doing it because it allows the use of more state safe practices in functional programming.\n\nI want to show a simple example of how thinking functionally can help the quality of life in Android. If you are an Android developer, you have written a ton of RecyclerView Adapters. Despite the fact that most adapters are going to be pretty basic you have to create a whole new class. Why not just have a function that will do all the that work for us that we can just reuse when creating a simple adapter.\n\n```kotlin\ninline fun simpleAdapter(data: List = emptyList(), viewLayout: Int, crossinline bindViewHolder: (holder: RecyclerView.ViewHolder, item: T) -> Unit) = object : RecyclerView.Adapter() {\n override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\n return object : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(viewLayout, parent, false)) {}\n }\n\n override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) = bindViewHolder(holder, data[position])\n override fun getItemCount(): Int = data.size\n```\n\nNotice the last parameter this function takes is another function that is invoked by the adapter when onBindViewHolder is called. Let’s look at how we use this function.\n\n```kotlin\ninline fun simpleAdapter(data: List = emptyList(), viewLayout: Int, crossinline bindViewHolder: (holder: RecyclerView.ViewHolder, item: T) -> Unit) = object : RecyclerView.Adapter() {\n override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\n return object : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(viewLayout, parent, false)) {}\n }\n\n override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) = bindViewHolder(holder, data[position])\n override fun getItemCount(): Int = data.size\n```\n\nWhat this does besides saving time and class files is it restricts you from thinking of the adapter as a class. You can’t override all its methods and change everything about how they work to force it to work the way you think it should. You have no access to change the state of the data.\n\nI know this sounds terrifying but remember we can be our own worst enemies a lot of the time. So building safety walls to stop ourselves can be a really good thing.\n\n","author":"Lewis Rhine","date":"2016-12-07","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Composing functions in Kotlin with extensions and operators","url":"https://medium.com/@fourlastor/composing-functions-in-kotlin-with-extensions-and-operators-76a499f5b4b7#.72408kmql","body":"\nToday I was wondering if I could achieve a more elegant way to compose functions with Kotlin. Let’s imagine we have this:\n\n```kotlin\nfun same(val: Int) = val \nfun twice(val: Int) = val * 2 \nfun trice(val: Int) = val * 3\n```\n\n```kotlin\nfun composed(val: Int) = same(twice(trice(int)))\n```\n\nThat gets the job done, but wouldn’t it be better if there was a way to remove all those brackets and get something more similar to a pipeline? Keep in mind: the order of execution will be inverse (trice-twice-same), which is not intuitive.\n\nTurns out there is, if we use two awesome Kotlin features: [_extensions_](https://kotlinlang.org/docs/reference/extensions.html)and [_operator overloading_](https://kotlinlang.org/docs/reference/operator-overloading.html). What are those?\n\n### Extensions\n\n**Extensions** let you add extra methods to any type, calling them as if you were declaring a method inside that type. An example could be:\n\n```kotlin\nfun Int.double() { \n return this * 2 \n}\n```\n\n```kotlin\n2.double() == 4\n```\n\nThis basically means: add a method to the type `Int` with name `double`, which you can then invoke on any `Int`. The keyword `this` is used to get the instance on which you’re invoking the method (the _receiver_ object). How this works in more detail is compiling to a static method of which `this` is the first parameter.\n\nAn interesting thing is that, in Kotlin, a function can be used as a type too! So we might be able to write something like this, as an extension function:\n\n```kotlin\nfun (() -> Unit).andHello() { \n this() \n println(\"Hello, world!\") \n}\n```\n\n```kotlin\nfun greet() { \n println(\"Hey there!\") \n}\n```\n\n```kotlin\nfun greetAndHello() { \n ::greet.andHello() \n}\n```\n\n`() -> Unit` is the way you can describe a function type (you’d do the same if it was a parameter). Inside the `()` you would put the parameters, `Unit` means it’s a `void` function (otherwise it would be the return type, for example `(Int, Int) -> Int` would be a function taking 2 `Int` parameters and returning an `Int`.\n\nHere we are referencing a function with the `::` operator, and applying the `andHello()` method to it. Pretty neat!\n\n### Operator overloading\n\nImagine you have an interesting type, and you’d like to use some standard operators with it. Wouldn’t it be great, for example, if you could access the elements in a map simply using square brackets? You can indeed!\n\n```kotlin\nval map = mapOf(\"a\" to 1, \"b\" to 2, \"c\" to 3)\n```\n\n```kotlin\nprintln(map[\"a\"]) // 1\n```\n\nHow does this work? Via **operator overloading**: you declare a method with the keyword `operator` in front of it, plus a certain name and signature, and then implement the method as you would do with any other method.\n\n```kotlin\nclass Map { \n operator get(key: Key): Value { \n // get and return the value from the map here \n } \n}\n```\n\nYou can then use the operator on that type normally. That can come in handy to redeclare operators in a way that makes more sense for your classes (maybe you want to sum two`Time` instances together?).\n\nYou can find the full list of available operators and respective signatures in the [operator overloading documentation page](https://kotlinlang.org/docs/reference/operator-overloading.html).\n\nSo, let’s take a small leap and imagine this is the final result we wanted:\n\n```kotlin\nfun composed(val: Int) = (::trice..::twice..::same) (val)\n```\n\nWhat are we trying to achieve? It’s pretty clear: we want to call, in sequence, in this order, the functions. Notice how the call order is now reversed compared to the first example (and makes it easier to read).\n\nI’m using the `..` operator (range) because it reminds me of _chaining_ when we talk about functions. For example, it’s used to call multiple methods in sequence on an object in Dart.\n\nHow could we achieve that? All those functions are receiving one parameter and returning something, and we know that we can create an extensions for it.\n\n```kotlin\noperator fun ((T) -> R).rangeTo(other: (R) -> V): ((T) -> V) { \n return {other(this(it)) \n }}\n```\n\nWhat is this? Let’s go one step at a time.\n\nFirst of all, we’re declaring an operator overload. The `rangeTo` method represents the `..` operator.\n\nWe’re declaring this extension on _any_ function of type `(T) -> R` so any function that takes a parameter of type `T` and returns a type `R`. Notice that `T` and `R` can be the same (for example, `Int`s).\n\nThis extension accepts another function, of type `(R) -> V`, so it will take the previous function return type and return another type.\n\nFinally, this will generate another function, of type `(T) -> V` which is what we expect after calling both functions.\n\nWith the acquired knowledge, let’s look at this again, does it make more sense?\n\n```kotlin\nfun composed(val: Int) = (::trice..::twice..::same) (val)\n```\n\nWe’re applying the `..` operator to `trice`, `twice`, and `same`, in order. Since the return type is a function, the result of `::trice..::twice` can be then chained with `::same`. The result of this last operation is again a function, which then we invoke with `(val)` as an argument.\n\nKotlin metaprogramming features are extremely intersting, and give you the chance to make your code more expressive, especially when you combine features like extensions and operator overloading. This is only a small example of what you can achieve, so start playing with it if you aren’t already!\n\n","author":"Daniele Conti","date":"2016-10-27","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Corda: Kotlin","url":"https://www.corda.net/2017/01/10/kotlin/","body":"\nWhen people start looking at Corda’s code the things they notice immediately is that it’s written in [Kotlin](https://kotlinlang.org/), a new programming language from JetBrains that targets the JVM and Javascript. This was an unusual choice, so in this post I’ll give some background on why we did it and discuss experiences from our “year of enterprise Kotlin”.\n\n## Why Kotlin?\n\nWe can break this decision down into two parts:\n\n1. Which platform to use? JVM, .NET, Node, Python/Ruby, Go, Haskell or native?\n2. Having selected the JVM, which language targeting it? Java? If not, why not? And if not, then which of Scala, Ceylon, Clojure, Kotlin, Python, Ruby, Javascript or Haskell to use (as they all have implementations that target the JVM).\n\nThe reasons for choosing the JVM as a platform are well understood in the enterprise space and not something that needs to be dwelled on much here. Suffice it to say that if you want a scalable, thread-safe, garbage collected, cross platform runtime with a very large collection of well documented libraries that solve common business tasks then your field has already been narrowed to just the JVM and .NET.\n\nAt the time Corda started development, it didn’t have a name and it wasn’t clear that it’d go ahead and turn into a product. In fact, when the project that would become Corda began in December 2015 (my first day on the job), there were no plans to build a new enterprise distributed ledger. Corda started out as a collection of prototypes to explore some new ideas and requirements that the consortium’s _Architecture Working Group_ was interested in, particularly around limited data visibility, and a data model that gave the scalability of the “UTXO set” approach along with the generic programmability of Ethereum’s imperative smart contracts.\n\nBecause it wasn’t clear if these prototypes would turn into anything or just inform the thinking of other products on the market, we faced a tricky choice: on one hand, we wanted to rapidly explore algorithms and data structures in a way that was productive. On the other, it needed to be something that could still be used to build a large enterprise product and for which we could rapidly hire.\n\nJava obviously fit the bill, but its lack of modern conveniences significantly reduces productivity and, more subtly, developer morale.\n\nDynamic typing was out: the correctness, tooling and performance benefits of static typing are too great to ignore.\n\nLanguages radically different from the mainstream are also out, as we wanted to be able to hire financial industry domain experts – whilst building a team around languages like Haskell [is by no means impossible](https://lexi-lambda.github.io/blog/2016/06/12/four-months-with-haskell/), intersecting people with serious banking experience _and_ lazy pure functional languages _and_ who happen to live in London felt risky. In addition, the nature of the product means our “users” are actually plugin/app developers who build on the platform, and it wouldn’t make sense to require them to learn entirely new paradigms and toolchains. Our choice of language should not constrain our users too much.\n\nAdded up, these requirements left us with Kotlin, Scala and Ceylon. All are rather similar languages and all were quite appealing. We went for Kotlin for these reasons:\n\n* Near seamless Java interop\n * In particular, Kotlin programs use a compiler-enhanced version of the regular JDK collections. Thus there are no interop issues created by the use of a different collections library. Passing collections in and out of Java libraries is something we do all over the place in Corda, so it’s important that this be painless.\n * Kotlin classes produce ordinary looking Java APIs with get/set/is methods as appropriate for the type. No special annotations or effort is required. Because Corda exposes an API that is intended to be transparently usable by Java developers, this is a big win: ordinary code tends to produce APIs that can’t be told apart from a Java API, with only a few minor aspects needing thought (e.g. you need to manually annotate methods to specify that they throw checked exceptions, otherwise they aren’t catchable from Java).\n* Inlining of small functions like map/filter/fold/groupBy is done by the compiler frontend instead of relying on the JVM to do it. Unfortunately the JVM’s JIT compilers, whilst generally excellent, don’t reliably remove the overhead of heavy use of higher order functions. Using Kotlin fixes this, along with allowing you to do flow control inside the lambda functions. This is the kind of feature that’s obscure but adds up, as we write code in this functional style all over the place and could easily dig ourselves into a performance hole if this style translated badly to machine code.\n* Because Kotlin code translates to equivalent Java very closely, almost all existing Java-oriented tools work out of the box. This isn’t always true of other languages, for instance, Quasar struggles to instrument Scala code because it wants method annotations and Scala translates lambdas to methods that can’t be annotated. Kotlin lambdas are often inlined anyway (see above) and can be annotated when not.\n* Excellent documentation and tiny standard library makes it a very fast language to learn. We do not explicitly advertise our positions as needing Kotlin experience and have been hiring people who didn’t know it already, with ramp-up times in the range of 1-3 days before the new team member is producing idiomatic code.\n* IntelliJ is the most popular IDE, judging from what our interview candidates select (they have a free choice of tools). Kotlin has the best IntelliJ support of all the post-Java languages.\n* I already had experience with it and had found it to be enjoyable, so I felt confident new team members would enjoy it too.\n\nIf Kotlin didn’t exist we’d probably have gone with Scala instead: it is heavily inspired by Scala and they’re both great languages.\n\n## Our year of Kotlin\n\nSo what was it like, using a new language in an enterprise context for a year?\n\nThe highlight has undoubtedly been spontaneously hearing from team members how much they’re enjoying working with it. Programming languages are a very personal thing and people tend to have strong opinions on them. When you ask people to learn a new language as the first task in their new job, and when you don’t even _tell_ developers that this is what you’ll be doing, there’s always a risk that some team members will just hate it and find it hurts rather than helps their productivity. That hasn’t been an issue here.\n\nSome issues that frequently crop up in the post-Java/C# enterprise space and our experiences:\n\n* **Code that looks very different depending on who wrote it.** By and large not a big issue. Unlike Go, which mandates a particular code style, Kotlin code written by different authors can look different. But IntelliJ has a reformatter tool that is capable of unifying code style across the codebase. It’s more limited than the Java equivalent, but has been sufficient. A more subtle issue that can crop up, especially with Scala codebases, is Java-OOP vs Haskell-FP style coding. Scala code that uses libraries like scalaz [can prove difficult to read](https://gist.github.com/folone/6089236) for people who are expecting to see a better Java. Kotlin comes down pretty firmly on the better Java side of the debate, and [although you can do some kinds of functional programming in Kotlin](https://blog.plan99.net/kotlin-fp-3bf63a17d64a#.lmrq68n03), the community hasn’t divided into camps (at least, not yet). We’ve had some cases where code was written as if it were Haskell, but that has got worked out in code review.\n* **Libraries.** We use over 50 open source libraries in Corda and they have all been painless. We have not found ourselves writing wrapper or adapter layers. Kotlin projects typically use Gradle or Maven as their build system: there’s no official Kotlin-specific replacement for these tools (though Gradle is adopting Kotlin as its new scripting language!).\n* **SQL DSLs.** C# has LINQ, Java has jooq and Kotlin has [Exposed](https://github.com/JetBrains/exposed). This is an area where Kotlin is a bit weaker than the competition: Exposed is a great example of how to use Kotlin’s DSL building features, but the library itself does not have a stable API and is a side project. Jooq can of course be used from Kotlin as well and in hindsight that would probably have been a better route to go.\n* **IDE/tooling.** The Kotlin plugin for IntelliJ is of course also written by JetBrains and is generally superb. However, it’s not quite as sophisticated as the Java support is. New editor features like [parameter hints](https://blog.jetbrains.com/idea/2016/09/intellij-idea-2016-3-eap-faster-git-log-parameter-hints-and-more/) have to be manually ported to Kotlin and as such support tends to lag behind the much older Java plugin. We’ve also found the IDE plugin to report internal errors quite frequently, although the frequency of IDE exceptions has fallen dramatically over the course of the year (and they don’t seem to impact anything when they occur). Tooling is also pain-free, as tools written for Java typically work out of the box. The exception are tools that actually parse source code rather than bytecode: those obviously cannot be reused.That said, Kotlin’s compiler and IDE plugin are not as robust as Java’s even a year after the 1.0 release. You basically never encounter internal compiler errors in javac. They are something we do still encounter in Kotlin on rare occasions.\n* **Customer acceptance.** Corda’s users are typically large, conservative financial institutions. Such companies tend to prefer the use of well known, established languages. Kotlin, being neither, obviously raised some eyebrows when we started out. “Why Kotlin” is a question that has largely faded away over the past year as people looked closer and realised that it wasn’t as risky as new languages typically are.We have also tried to address this by providing Java code samples to prove that developers can build on the platform without having to learn Kotlin. There we’ve been a bit less successful: many developers who are new to Corda still start out by getting familiar with Kotlin first. It’s a bit unclear if this is because we don’t provide enough Java-specific samples and docs or whether it’s a good excuse to learn a cool new tool. We’ve also been assisted here by the growing acceptance of Kotlin inside the large investment banks. We’ve heard from several consortium members over the past year that their internal software development teams have started seriously looking at Kotlin for their own use: often prompted by the existence of the Java-to-Kotlin converter tool that makes introduction into an existing codebase much more seamless.\n* **Commercial support.** A risk with using obscure languages is that they might not stick around, or might have goals that are not compatible with the needs of the user base that grows around the product (e.g. in the case of research languages where the primary goal of the developers is to publish papers). One reason we felt comfortable going with Kotlin is that JetBrains is a stable, profitable company that has been around for over 15 years. JetBrains is rapidly “eating its own dogfood” by introducing Kotlin code into the core of its primary products; thus there is little risk of it becoming unmaintained. Additionally, JetBrains is old enough that its core market (IDEs and developer productivity tools) is no longer particularly fashionable or new, giving a low risk of a corporate buyout that causes an unpredictable strategy change.Whilst there are no commercial support packages available for Kotlin, in practice the team fixes reported issues pretty fast. JetBrains are currently aiming to release the next major upgrade of the language about a year after 1.0, a release cycle which is quite compatible with enterprise development cycles.\n\n## Conclusion?\n\nWe have no regrets: picking an unproven language at the start of this project was a risk, but a calculated one. It’s worked out well for us and we’d do it again.\n","author":"Mike Hearn","date":"2017-01-10","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Lessons from converting an app to 100% Kotlin","url":"https://medium.com/keepsafe-engineering/lessons-from-converting-an-app-to-100-kotlin-68984a05dcb6#.ymxam7e1t","body":"\n### Lessons from converting an app to 100% Kotlin\n\nI’ve been following the development of [Kotlin](https://kotlinlang.org) for a while. Kotlin is a relatively new language that primarily targets the JVM, and is interoperable with Java. With the release of Kotlin version [1.0.2](https://blog.jetbrains.com/kotlin/2016/05/kotlin-1-0-2-is-here), which brought incremental compilation and a large reduction in the number of methods in its standard library, I was eager to start using it in production.\n\nI’m the lead engineer on [App Lock](https://play.google.com/store/apps/details?id=com.getkeepsafe.applock) at [Keepsafe](https://www.getkeepsafe.com), which, like most Android apps, was written in Java. There are quite a few places where Java falls short of modern languages, especially the version of Java 7 that Android supports. To reduce the pain, it is common to use libraries such as [Retrolambda](https://github.com/evant/gradle-retrolambda) for a backport of lambdas and try-with-resources, [Guava](https://github.com/google/guava) for immutable collections and utility functions, [ButterKnife](https://github.com/JakeWharton/butterknife/) for view binding, or [ReactiveX](https://github.com/ReactiveX/RxJava) for functional programming. All of those libraries come with drawbacks, though. Retrolambda frequently causes incremental builds to fail, and every library you depend on adds methods to your APK.\n\nEven with those libraries, Java code is verbose. Your code has to go through a lot of ceremony that the designers of Java thought was a good idea in the 90s, but is clearly unnecessary today. Kotlin provides a well thought-out syntax and extensive standard library that removes many of the pain points that exist in Java. So over the course of a few days, I converted the entire App Lock codebase into Kotlin. Here are my thoughts on the process.\n\n### Kotlin vs Java in App Lock\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*0JjkzvEAP17sK28Ud12QqQ.png)\n_Method count in App Lock after converting to Kotlin. From the dexcount gradle plugin._\n\nOne concern that people will raise about converting to Kotlin is the number of methods added by its standard library. Thanks to massive libraries like the support library and GMS, many apps are in danger of bumping up against the [Dex method limit](https://developer.android.com/studio/build/multidex.html). I used the [dexcount gradle plugin](https://github.com/KeepSafe/dexcount-gradle-plugin) to break down the method count before and after the rewrite. The end result is that the total method count after proguard _decreased_ by 10% from 5491 to 4987 (not counting GMS or appcompat). The code count decreased by 30% from 12,371 lines of Java, to 8,564 lines of Kotlin.\n\n> Converting the app from Java to Kotlin reduced the total method count by 10%, and the total lines of code by 30%\n\nThe method count decrease is a result of both Kotlin being a more concise language, as well as the fact that many of the quality of life libraries that were previously used in Java are no longer necessary.\n\n#### Retrolambda\n\nRetrolambda generates an anonymous class for every lambda which add several methods each. Kotlin has inline methods to which a lambda can be passed without adding any extra methods.\n\nFor example, the extremely useful standard library function [_apply_](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html):\n\n```kotlin\npublic inline fun nT> T.apply(block: T.() -> Unit): T { \n block(); return this \n}\n```\n\nWhich is called like this:\n\n```kotlin\nmyObject.apply **{** /* modify myObject */ **}**\n```\n\nEven though you’re defining a lambda function at the call site, no anonymous class is generated, so no extra methods are added, and no allocation happens due to that call. In fact, the _apply_ function itself, like most inline functions in the Kotlin standard library, doesn’t cause a method to be added in the compiled code.\n\n#### Guava\n\nThe entirety of Guava is covered by the Kotlin standard library, which has the additional advantage of being easier to use. Big Guava ComparisonChains can be replaced with a few characters with the [kotlin.comparisons functions](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.comparisons/index.html).\n\n```java\n// Guava \nComparisonChain._start_() \n .compareTrueFirst(lhs.isActive(), rhs.isActive()) \n .compare(lhs.lastName(), rhs.lastName()) \n .compare(lhs.firstName(), rhs.lastName()) \n .result();\n```\n\n```kotlin\n//Kotlin \n_compareValuesBy_(lhs, rhs, \n **{it**.active**}**, **{it**._lastName_**}**, **{it**._firstName_**}**)\n```\n\nThe null safety of Guava’s Optional class is [built in to Kotlin](https://kotlinlang.org/docs/reference/null-safety.html).\n\n```java\n// Guava \nreturn Optional._of_(value).or(defaultValue);\n```\n\n```kotlin\n// Kotlin \nreturn value ?: defaultValue\n```\n\nGuava’s lazy fields and Preconditions classes are covered by the [Kotlin standard library](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/index.html).\n\n```java\n// Guava \nprivate Supplier lazyField = Suppliers._memoize_( \n () -> \"value\"); \npublic String getField() { \n return lazyField.get(); \n}\n```\n\n```kotlin\n// Kotlin \nval field by _lazy_ **{** \"value\" **}**\n```\n\n```java\n// Guava \nPreconditions.checkNotNull(value, \"error %s\", arg);\n```\n\n```kotlin\n// Kotlin \n_checkNotNull_(value) **{**\"$arg\"**}**\n```\n\nNearly all of Guava’s collections classes [exist in Kotlin](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/index.html). Even with all of that functionality, the entire Kotlin standard library is still smaller than Guava alone.\n\n#### ButterKnife\n\nButterKnife can still be used in Kotlin, but the [Kotlin Android Extensions](https://kotlinlang.org/docs/tutorials/android-plugin.html) provide a more natural way to access bound views. Other solution also exist such as [Kotterknife](https://github.com/JakeWharton/kotterknife) and [Anko](https://github.com/Kotlin/anko), but I find that regular XML layouts with the Kotlin Android Extensions are currently the best way to work with Views. Kotterknife requires more boilerplate than the extensions. Anko adds thousands of methods, and its DSL is often more complicated and less capable than XML.\n\n#### RxJava\n\nRxJava is still awesome, and I still use it in many places in App Lock. But since Java on Android doesn’t have functional methods on collections, I will sometimes use RxJava as a substitute. Something like this in Java:\n\n```kotlin\nObservable.from(collection) \n .filter(it -> it.isActive()) \n .map(it -> it.size()) \n .reduce((it, sum) -> it + sum) \n .toBlocking().single();\n```\n\nCan be replaced with this in Kotlin:\n\n```kotlin\ncollection.filter { it.isActive() } \n .map { it.size() } \n .reduce { it, sum -> it + sum }\n```\n\n### Getting started with Kotlin\n\nIf you already know Java, learning Kotlin is easy. You can work through the [Kotlin Koans online](http://kotlinlang.org/docs/reference/), and the [reference documentation](http://kotlinlang.org/docs/reference/) is very well written. Jake Wharton also gave a [great talk about some of the useful syntax features in Kotlin](https://vimeo.com/144877458).\n\nThe best part about Kotlin is that it can be called from Java, and Java can be called from Kotlin. So you don’t need to convert your entire codebase at once. I would suggest you start with a single file that you rewrite from scratch. IntelliJ has an automated Java-to-Kotlin converter, but it frequently produces incorrect code, so it’s better to start from scratch until you have a better handle on the language.\n\nOnce you have the basics down, I recommend picking some existing Java code that has few dependencies, and converting it to Kotlin. UI code like an Activity of Fragment on Android is a good place. Picking a class with no dependencies allows you to focus on just the code you’re working on without worrying about how any interfaces are changing. Keep the [Kotlin reference](https://kotlinlang.org/docs/reference/) open so that you can quickly answer questions about syntax or the standard library that come up while you’re working. You could also choose to start new Kotlin code from scratch instead of converting from Java, but I find that it’s easier to pick up some of the less obvious syntax from converted code than trying to figure it out from a blank slate. The automated conversion does a really good job in most cases, and the places where it fail are usually easy to fix.\n\nSomething to keep in mind while you’re learning Kotlin is to avoid getting overwhelmed. If you don’t already use a design pattern like MVP or MVVM, don’t worry about try to learn it at the same time. Don’t worry about finding every Kotlin library available. Just focus on taking what you know about Java and translating that knowledge to Kotlin. If you still have pain points, then you can add more libraries or design patterns.\n\n### Should you convert your entire codebase at once?\n\nAfter you’ve got some Kotlin working in your codebase, you’ll have to decide whether or not to convert everything at once, or take it more slowly. Fortunately, Kotlin has excellent two-way interoperability with Java, so you can convert single classes at a time, and ship with both languages running together.\n\nFor large codebases, it can be too much work to convert everything in one release. In [Keepsafe’s main app](https://play.google.com/store/apps/details?id=com.kii.safe), about 15% of the code is Kotlin as of this writing. In that app, if we have to make significant changes to a Java class, we’ll usually convert the class to Kotlin while we’re working on it. This allows us to steadily improve the codebase without slowing down our work on new features.\n\nHowever, if your project is small enough that you can convert to 100% Kotlin, it’s something worth considering. When you don’t have to maintain Java compatibility, you can simplify your internal APIs and remove a lot of the libraries I talked about earlier. You can convert static utility classes into extension functions, and take advantage of the stronger type inference in Kotlin.\n\n### Final thoughts\n\nKotlin is a great language, and is a huge improvement over Java. Converting App Lock to Kotlin resulted in an app that was faster, smaller, and which had fewer bugs than before. The language is mature enough now that there were no important features missing, in either the tooling, the language, or the standard library. If you’re wondering whether to give Kotlin a try now or if you should wait a while longer, I can tell you that Kotlin is ready for full time production use now. If you work with Android or another Java environment where Kotlin is a possibility, you owe it to yourself to give Kotlin a try.\n\n\n_This is the first post of a series of two. Follow_ [_Keepsafe Engineering_](http://www.keepsafe.tech) _to get notified about future posts. Interested in writing Kotlin code your self? Have a look at our_ [_Kotlin job opening_](https://jobs.lever.co/keepsafe/6414e440-ed8e-4c1e-a156-6e4e1b716577)_._\n","author":"AJ Alt","date":"2016-08-10","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"5 small things you probably don’t know about Kotlin","url":"https://medium.com/@piotr.slesarew/5-small-things-you-probably-dont-know-about-kotlin-255261940de6#.pgfivsdr7","body":"\n> There are known knowns. These are things we know that we know. There are known unknowns. That is to say, there are things that we know we don’t know. But there are also unknown unknowns. There are things we don’t know we don’t know. — Donald Rumsfeld\n\nI have been using Kotlin for almost a two years and I started from putting it to toy project intended for my tech talks. Do you remember that time when Kotlin had _traits_ instead of _interfaces_? From the very first line, I knew that this language will change my life, and you know what? I was totally right.\n\nKnowledge makes you better and that is why world’s most successful engineers are constantly learning new things. Here is my list of five less known things about Kotlin and I hope you will find at least three worth knowing.\n\n### 1. Name your imports\n\nIn Kotlin, _imports_ are used by the compiler to let you name your classes by their unqualified name. What happens if you have naming conflict? Sad things happen!\n\n```kotlin\npackage com.code.sliski.userinfoscreen.ui\n\nimport ...\n\nimport android.view.View // Conflict\n\nclass UserInfoFragment : Fragment(), com.code.sliski.userinfoscreen.ui.View { // Conflict\n\n override fun onCreateView(inflater: LayoutInflater, \n container: ViewGroup?, \n state: Bundle?): View = // Conflict\n inflater.inflate(user_info_fragment,\n container,\n false)\n}\n\ninterface View // Conflict\n```\n\nPersonally, I hate using fully qualified package names in my code as it lowers readability and clarity. **In Python, you can name your imports to fix the conflicts and Kotlin supports it as well** ❤.\n\n```kotlin\nimport android.view.View as AndroidView // Named import\n\nclass UserInfoFragment : Fragment(), View {\n \n override fun onCreateView(inflater: LayoutInflater, \n container: ViewGroup?, \n state: Bundle?): AndroidView = // Using named import\n}\n```\n_Refactored code using named import_\n\n### 2. Change companion object name\n\nCompanion object was introduced to replace static members. It is not only for declaring static properties but also to name them. How? Let’s have a look at this example.\n\n```kotlin\n// Using in Java\nCustomButton button = new CustomButton(context);\nbutton.setVisibility(CustomButton.Companion.getGONE());\n\n// Using in Kotlin\nval button = CustomButton(context)\nbutton.visibility = CustomButton.VISIBLE\n\nclass CustomButton(context: Context?) : View(context) {\n companion object {\n // Visibility\n val GONE = 1\n val VISIBLE = 2\n val INVISIBLE = 3\n }\n}\n```\n\nBy default, Kotlin creates a static nested class _Companion_ for every companion object. That is why you need to use _CustomButton.Companion_ to access static members from Java code(you can also use it in Kotlin but it is not necessary). **Kotlin lets you change the default name of companion object to whatever name you want.** Refactored code looks like this.\n\n```kotlin\n// Using in Java\nCustomButton button = new CustomButton(context);\nbutton.setVisibility(CustomButton.Visibility.getGONE());\n\n...\n\nclass CustomButton(context: Context?) : View(context) {\n companion object Visibility {\n val GONE = 1\n val VISIBLE = 2\n val INVISIBLE = 3\n }\n}\n```\n\nThe biggest drawback is that Kotlin does not support multiple companion objects for a class. It would be great for grouping static properties.\n\n```kotlin\n// Using in Java\nCustomButton button = new CustomButton(context);\nbutton.setVisibility(CustomButton.Visibility.getGONE());\n\n...\n\nclass CustomButton(context: Context?) : View(context) {\n companion object Visibility {\n val GONE = 1\n val VISIBLE = 2\n val INVISIBLE = 3\n }\n}\n```\n\nThis code does not compile because Kotlin supports only one companion object per class\n\n### 3. Compose functions\n\nI bet you used function references before but have you ever tried to use them to compose functions? Imagine that you want to map an array of prices to prices that are taxed, discounted and rounded. Using common approach you will end up with something like this.\n\n```kotlin\nval prices = listOf(21.8, 232.5, 231.3)\nprices.map(::taxed)\n .map(::discounted)\n .map(::rounded)\n\nfun taxed(value: Double): Double = value * 1.4\nfun discounted(value: Double): Double = value * 0.9\nfun rounded(value: Double): Double = Math.round(value).toDouble()\n```\n\nThis example is begging for composition so do not disregard it and make the code better place. Abracadabra!\n\n```kotlin\nval prices = listOf(21.8, 232.5, 231.3)\nval taxedDiscountedRounded = compose(::taxed, ::discounted, ::rounded)\nprices.map(taxedDiscountedRounded)\n\nfun compose(f: (A) -> A,\n g: (A) -> A,\n h: (A) -> B): (A) -> B = { x -> h(g(f(x))) }\n\nfun taxed(value: Double): Double = value * 1.4\nfun discounted(value: Double): Double = value * 0.9\nfun rounded(value: Double): Double = Math.round(value).toDouble()\n```\n\n**Functions composition not only makes your code cleaner but also faster.** Once you understand it, you will be able to compose almost everything.\n\n### 4. Change name of generated class\n\nExtension functions are one of the most attractive features in Kotlin but using them in Java code can give you a serious headache. It is ugly and besides is nothing else like invoking a static method.\n\n```kotlin\n// Main.java\npublic static void main(String[] args) {\n String name = null;\n\n AnyKt.ifNull(name, new Function1() {\n @Override\n public Unit invoke(Object o) {\n return null;\n }\n });\n}\n\n// Any.kt\ninline fun T?.ifNull(function: (T?) -> Unit) {\n if (this == null) function(this)\n}\n```\n\nKotlin generates class _AnyKt_ with a static method so you can use it in Java. **There is an option to change the name of generated class to achieve better readability.**\n\n```kotlin\n// Main.java\npublic static void main(String[] args) {\n String name = null;\n\n Nullcheck.ifNull(name, new Function1() {\n @Override\n public Unit invoke(Object o) {\n return null;\n }\n });\n}\n\n// Any.kt\n@file:JvmName(\"Nullcheck\")\npackage ...\n\ninline fun T?.ifNull(function: (T?) -> Unit) {\n if (this == null) function(this)\n}\n```\n\n### 5. Validate an assignment and “veto” it\n\nThe way in which Kotlin handles delegation is pretty spectacular so if you are not familiar with it, you should totally check my article: “Zero boilerplate delegation in Kotlin”.\n\nBesides of “class delegation”, there is an interesting mechanism called “delegated properties”which is used for _lazy_ property initialization. How would you solve scenario in which you need to be able to intercept an assignment and “veto” it? Is there any clean way to do it? Yes, there is!\n\n```kotlin\nvar price: Double by Delegates.vetoable(0.0) { prop, old, new ->\n validate(new)\n}\n\nfun validate(price: Double) : Boolean {\n // Validation checks\n}\n```\n\nSample shows usage of a built-in _vetoable_ delegate. Lambda passed to the _vetoable_ is called before the assignment of a new value to property. **Returning false from the lambda allows you to “veto” the assignment but if you want to pass it through return true.**\n\n![](https://cdn-images-1.medium.com/max/880/1*gkc1Y_YumE5sIffEmO03Yw.jpeg)\n\n[http://looneytunes.wikia.com/wiki/That's_All_Folks](http://looneytunes.wikia.com/wiki/That%27s_All_Folks)\n\n","author":"Piotr Ślesarew","date":"2016-11-25","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Mocking Kotlin with Mockito","url":"http://hadihariri.com/2016/10/04/Mocking-Kotlin-With-Mockito/","body":"\n## The un-mockable\n\nGiven that by default Kotlin classes and functions are final (i.e, you need the `open` modifier to be able to inherit from them), when trying to mock behaviour in tests, you’re often left with no choice other than to declare these `open` or introduce interfaces solely for the purpose of testing. Neither of these are really great.\n\nFor instance, given the following code\n\n```kotlin\nclass LoanCalculator {\n fun calculateAmount(customerId: Int): Double {\n return 100.0 * customerId\n }\n}\n\n```\n\nand a class that uses the above\n\n```kotlin\nclass LoanService(val loanCalculator: LoanCalculator) {\n fun authoriseCustomerLoan(customerId: Int): Double {\n if (customerId != 0) {\n return loanCalculator.calculateAmount(customerId)\n }\n return 0.0\n }\n}\n\n```\n\nIf I want to be able to mock the `calculateAmount` function, I could write something like the following\n\n```kotlin\n@Test\nfun authoriseCustomerLoan() {\n val mockLoanCalculator = mock(LoanCalculator::class.java)\n `when`(mockLoanCalculator.calculateAmount(3)).thenReturn(300.0)\n val loanService = LoanService(LoanCalculator())\n val amount = loanService.authoriseCustomerLoan(3)\n assertEquals(300.0, amount)\n\n}\n```\n\nbut on running it, Mockito would complain indicating that it cannot mock a class/method that is final.\n\n## MockMaker\n\n[Mockito 2](http://mockito.org/) solves this. With the recent [release of version 2](https://github.com/mockito/mockito/wiki/What's-new-in-Mockito-2), one of the big changes is the ability to mock the un-mockable. In other words, you can mock final classes in Java and consequently all classes and member functions in Kotlin.\n\nIn order to take advantage of this feature, you write your code in exactly the same way you would for mocking an open class/function. However, you need to perform an additional step which basically consists in creating a file named `org.mockito.plugins.MockMaker` and placing this under the `resources/mockito-extensions` directory in your test folder[1].\n\nThe file contains a single line:\n\n```\nmock-maker-inline\n```\n\n![Mockito Resource Folder](http://hadihariri.com/images/mockito-1.png) \n\nIf you’re using Gradle, you can also have it [generate the file for you.](https://github.com/hhariri/mockito-sample/blob/master/build.gradle#L16). You can download the [sample project I’ve created from GitHub](https://github.com/hhariri/mockito-sample/)\n\nFinally, a big kudos to [Rafael](https://twitter.com/rafaelcodes) for his work in making this possible!\n\n[1] This feature is still new and plans are to make it easier to configure as they receive feedback on its usage.\n\n","author":"Hadi Hariri","date":"2016-10-04","type":"article","categories":["Kotlin","Testing"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Issues Faced With Kotlin During Android Development","url":"http://blog.bilue.com.au/issues-faced-with-kotlin-during-android-development-1","body":"\n[Kotlin](https://kotlinlang.org/) seems like the future of Android development. It is a new statically-typed programming language that runs on JVM, with a very refined syntax and enhanced features. There is a lot to love about it. Kotlin is interoperable with Java, which should reduce the risk of future incompatibility. The additional language features such as Function Extensions and High Order Function make it much more extensible and scalable. The code is concise with data classes, single expression function, infix and many more... enough said. Kotlin is just great!\n\n![Screen_Shot_2016-08-10_at_2.10.19_pm.png](http://offers.bilue.com.au/hs-fs/hubfs/Screen_Shot_2016-08-10_at_2.10.19_pm.png?t=1470802416157&width=733&height=294) \n\nI started working on some real apps using Kotlin that have since been published on the playstore. I have to say it was relatively smooth sailing. Nonetheless, there were some hiccups along the way that are worth sharing.\n\n### **1. Method Count Increase.**\n\nMethod count increase was one of the issues I was fully aware before starting with Kotlin. At the time of writing, there are an additional [7’191 methods](https://blog.jetbrains.com/kotlin/2016/03/kotlins-android-roadmap/) adding to the total method count. This would add more than 10% to the 65k methods limit. Nonetheless, I didn’t worry that much as the MultiDex support is there to help to overcome this issue.\n\n### **2. Using Libraries that require Annotation.**\n\nThere are many cool libraries that can assist with making Android Development much more efficient. However, when switching over to Kotlin, using some of them becomes a challenge. There are two libraries which I can’t manage to use directly after switching to Kotlin, i.) [Icepick](https://github.com/frankiesardo/icepick) and ii.) [EventBus](https://github.com/greenrobot/EventBus). The main reason is that the Annotation (i.e. _@State _and_ @Subscribe_) is not picked up by the code. Fortunately, with EventBus, I managed to work around this by creating a composite class object using Java Code. Note that this doesn’t mean all libraries using Annotation would not work for Kotlin. I managed to use [Retrofit 2.0](http://square.github.io/retrofit/) and [Dagger 2.0](http://google.github.io/dagger/) (where both use Annotation extensively) in Kotlin directly.\n\n### **3. Mocking Need Open Class/Function.**\n\nBy default a class and function is considered final for Kotlin. Mocking (using [Mockito](http://mockito.org/)) requires a non-final class. So in order to have that, we have to explicitly _open_ a class if we would like to mock it for testing. If this is not done, it would error out easily. The more tricky issue is the function. If the function is not _open_, there would be no error issue when running the test. Instead of intercepting the function, it would call the actual internal function, where the test would fail with NPE. Without knowing the function needs to be _open_, the root issue might not be easily discoverable.\n\n### **4. Java to Kotlin Converter Limitation.**\n\nThe Kotlin Plugin for Android Studio is just great, especially allowing to auto convert from Java to Kotlin. However, the conversion might not be ideal. e.g.\n\nis converted to\n\n```kotlin\nclass SimpleClass(memberVariable: Int) {\n internal var memberVariable = 0\n\n init {\n this.memberVariable = memberVariable\n }\n}\n```\n\nWhereby it could be as simple as\n\n```kotlin\nclass SimpleClass(val memberVariable: Int) {}\n```\n\nAnyway, it’s always good to review the converted code and explore so that we don’t just have Kotlin code in Java style, without the real advantage of Kotlin.\n\n### **5. Other Converter Issue.**\n\nI love writing a new function from an object, and pressing _Alt-Enter_ to trigger the auto-function creation. If you are writing on the Java side of code, and call a Kotlin function (that you just intended to create), sorry you are out of luck. Android Studio will only auto create that function for you in the Kotlin code.\n\nAt times for experimental purposes we would also like to convert from Kotlin to Java, given that it was inter-operable with Java. This is not possible however the tools only allow you to convert from Java to Kotlin and not vice versa. Perhaps this is by design, and I could imagine it would be difficult for Java to handle conversion of more advanced Kotlin language features.\n\nNone of these issues are show stoppers. The advantage and fun of learning new things outweighs them in any case. The language features are richer and there is so much to explore. I haven’t really faced many issues from Kotlin’s language as yet. I’m sure I’ll uncover more issues, but I don’t expect them to “kill me”. Java is always there to the rescue :)\n\nAs with any new thing, one other challenge is finding community support. Suppose you are experimenting with new Android Features and face a road-block. If you post your question to Stackoverflow using your Kotlin code, you are unlikely to generate support.\n\nSo... you might as well be the one who supports others... which is in itself a good thing! :)\n\n","author":"Elisha Lye","date":"2016-08-10","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Why I prefer Kotlin","url":"https://dev.to/grahamcox82/why-i-prefer-kotlin","body":"\nI've been an enterprise Java developer for a little over 10 years, and I've been using Java for just over 16 years - back when Java 1.3 was the latest and greatest. It's been a long ride. Back then there were no Lambdas, no Streams, no Generics, no Annotations. There wasn't even an `assert` keyword.\n\nThese days, Java has a huge amount for a very vast and powerful ecosystem. And one of the most powerful parts of all of that is the built in support for alternative languages as part of the same system. The JVM makes it possible to have many different languages - meaning the actual code you type into the editor - compile down to compatible bytecode and all run together in the same application. That's a huge benefit for software development, since you can now write different parts of the application in the best suited language for the job.\n\nSo what exactly is Kotlin, and why do I like it so much? Unlike many of of the other JVM languages, Kotlin doesn't try to be anything special or different. It simply exists as a vastly simplified, streamlined Java language. There is very little, if anything, that Java can do that Kotlin can't do. The difference is that Kotlin does the same in significantly less code, making it significantly easier to read and maintain. Kotlin also has a large emphasis on Java Interop, meaning that it's trivial to use it in conjunction with existing Java libraries. Some other JVM languages make this much harder to achieve, if it's possible at all.\n\nSo, in general, my experience so far is that Kotlin allows me to do everything that Java does, but simpler.\n\nThe only thing that I've struggled with at all was some of the tooling - but this really doesn't bother me that much. By this, I'm talking Code Coverage (The JVM bytecode includes many lines that just don't exist in the Kotlin code, so covering them is less easy), FindBugs, PMD, Checkstyle, and so on. I've not explored Sonar for Kotlin yet, but it's very likely that this will fill in many of the gaps if it works.\n\n","author":"Graham Cox","date":"2017-01-02","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.0.2 is Here","url":"http://blog.jetbrains.com/kotlin/2016/05/kotlin-1-0-2-is-here/","body":"\nWe’re happy to announce the release of Kotlin 1.0.2, the second bugfix and tooling update for Kotlin. In addition to compiler and language bugfixes, Kotlin 1.0.2 adds a number of major features to the IDE and the build tools.\n\n### Incremental Compilation in Gradle and the IDE\n\nThe new release continues our work on Kotlin incremental compilation support, speeding up the turnaround time during development. Incremental compilation in the IDE (which was previously marked as experimental) is now enabled by default. Also, the long-awaited support for **incremental compilation in Gradle builds** is now there.\n\nTo enable incremental compilation for Gradle, you need to set the **kotlin.incremental** property to true (for example, by adding the line `kotlin.incremental=true` to the `gradle.properties` file in the root directory of your project).\n\n### Android Lint Checks\n\nKotlin 1.0.2 introduces support for **Android Lint checks** for Kotlin code, ensuring that issues like using the API not available in the Android version you’re targeting are correctly detected.\n\nThe set of checks supported in Kotlin 1.0.2 corresponds to the checks supported in Android Studio 1.5; checks added or improved in Android Studio 2.0 will be supported in the next release of Kotlin. Also, the current version runs Lint checks for Kotlin code only inside the IDE (as part of on-the-fly code inspections, or in batch mode through Analyze | Inspect Code). Running checks from the command line will be supported in the next release.\n\n### Compact Standard Library\n\nOne other improvement relevant for Android developers is that the size of the standard library has been reduced by ~1500 methods (from approximately 6600 to 5100). Even before this change, the library was [smaller than those of Kotlin’s main competitors](https://github.com/SidneyXu/AndroidDemoIn4Languages), and now the situation is even better. Of course, the library is still fully binary compatible.\n\n### Java 7/8 Support Libraries\n\nAs a temporary workaround for better Java 7/8 support before full support is introduced in Kotlin 1.1, we’re now providing support libraries that expose the APIs added in Java 7 and 8 (such as the Stream API) as extension functions on Kotlin standard library classes. See the [forum post](https://discuss.kotlinlang.org/t/jdk7-8-features-in-kotlin-1-0/1625) for instructions on using the libraries.\n\n### IntelliJ IDEA Plugin features\n\nThe IntelliJ IDEA plugin has gained a number of major new features:\n\n* For users of Android Studio, there’s now a possibility to create a **new activity** in Kotlin;\n* For users of IntelliJ IDEA Ultimate, there is now initial support for the **Spring Framework**, including inspections, line markers, SpEL language injection support, actions to generate dependencies, and more;\n* A bunch of **inspections and quickfixes** have been added, such as an inspection for highlighting `var`s that can be `val`;\n* Improvements to Gradle integration, debugger, formatter, refactorings and other areas of the plugin.\n\n### JavaScript support\n\nWe’ve resumed work on our JavaScript backend, and the version 1.0.2 fills in most of the remaining gaps in the language feature support when targeting JavaScript. Newly supported features include nested classes, local classes, non-local returns in local lambdas, unsafe casts and more.\n\n### Maven Archetype\n\nWe’re now providing a Maven archetype to easily create Kotlin projects. Use “New project | Maven | Create from Archetype...” in IntelliJ IDEA, or the following command line:\n\n```kotlin\nmvn archetype:generate -Dfilter=org.jetbrains.kotlin:\n```\n\n### Dokka 0.9.8\n\nTogether with Kotlin 1.0.2, we’re releasing a new version of [Dokka](https://github.com/kotlin/dokka), the Kotlin documentation generation tool. If you’re using Dokka in your project, you need to upgrade Dokka together with Kotlin, because older Dokka versions are incompatible with Kotlin 1.0.2. New features in Dokka 0.9.8 include:\n\n* Android Gradle plugin, for generating documentation for Android libraries and applications;\n* Support for generating a javadoc jar file in the Maven plugin.\n\n### Conclusion\n\nYou can see the full list of bugfixes and changes to the compiler, standard library and the tools in the [changelog](https://github.com/JetBrains/kotlin/blob/1.0.2/ChangeLog.md).\n\nWhile working on the release, we received a lot of valuable feedback from the users of the [Early Access Preview builds](https://discuss.kotlinlang.org/t/kotlin-1-0-2-eap/1581). We’re really grateful to everyone who has provided feedback, and we welcome you to join the EAP program for future updates.\n\nAs usual, if you run into any problems with the new release, you’re welcome to ask for help on the [forums](https://discuss.kotlinlang.org/), on Slack (get an invite [here](http://kotlinslackin.herokuapp.com/)), or to report issues in the [issue tracker](https://youtrack.jetbrains.com/issues/KT).\n\n","author":"Dmitry Jemerov","date":"2016-05-13","type":"article","categories":["Kotlin","Release"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"KotlinLifeguard #1","url":"http://blog.makingiants.com/kotlin-lifeguard-1/","body":"\nUsing [@JvmOverloads](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-overloads/) tag helps to avoid multiple constructors with Kotlin\n\n## The headache\n\nIt’s really possible that you had some code like:\n\n```kotlin\nclass MyCustomView : FrameLayout {\n \n constructor(context: Context) : super(context) {\n init()\n }\n\n constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {\n init()\n }\n\n constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int)\n : super(context, attrs, defStyleAttr) {\n init()\n }\n\n fun init() { \n // ...\n }\n}\n```\n\nAs you can see there are all the constructors needed for a _custom_ `FrameLayout` but all with same “body”.\n\n![](http://blog.makingiants.com/assets/article_images/hmm.jpg)\n\n# The remedy\n\nRefactored with `@JvmOverloads`:\n\n```kotlin\nclass MyCustomView @JvmOverloads constructor(\n context: Context,\n attrs: AttributeSet? = null,\n defStyleAttr: Int = 0)\n: FrameLayout(context, attrs, defStyleAttr){\n\n init {\n // ...\n }\n}\n```\n\n## Thanks to\n\n* [Kotlin discuss](https://discuss.kotlinlang.org/t/simple-constructors-for-inheritance/1874/2)\n","author":"Daniel Gomez Rico","date":"2016-07-28","type":"article","categories":["Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Why You Must Try Kotlin For Android Development?","url":"https://medium.com/@amitshekhar/why-you-must-try-kotlin-for-android-development-e14d00c8084b#.2w8jdujf8","body":"","author":"Amit Shekhar","date":"2016-11-10","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin in Real Projects","url":"https://www.youtube.com/watch?v=lpPbCWpBM3I","body":"\n\n\n\n\n","author":"Anton Keks","date":"2016-11-01","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Functional Programming with Kotlin","url":"http://blog.jetbrains.com/kotlin/2015/11/webinar-recording-functional-programming-with-kotlin/","body":"\nThe recording of our October 22nd webinar, **Functional Programming with Kotlin**, is now available on [JetBrainsTV YouTube channel](https://youtu.be/AhA-Q7MOre0).\n\nIn this talk, Mike Hearn provides a brief introduction to programming in Kotlin via practical example: creating a textfield with the autocomplete suggestions while typing. Demo project is available on [GitHub](https://github.com/mikehearn/KotlinFPWebinar).\n\nTopics covered include:\n\n* Use of functional transforms\n* Immutability\n* Lazyness and working with lazy infinite sequences\n* The use of [funKTionale](https://github.com/MarioAriasC/funKTionale), a library that extends Kotlin with a few features known from Haskell\n* Pattern matching\n* Reactive user interfaces\n\n\n\nThe video includes the time stamps following the [agenda announced](http://blog.jetbrains.com/kotlin/2015/10/join-live-webinar-functional-programming-with-kotlin/):\n* `00:08` — Intoduction and demo application\n* `05:00` — `apply` function\n* `05:45` — Introduce NGram data class\n* `08:22` — Creating extension methods\n* `09:55` — Working with lazy infinite sequences\n* `10:35` — `map` function\n* `11:10` — `to` function and infix notation\n* `14:35` — Destructuring of data classes\n* `19:20` — `filter`, `let` and `all` functions\n* `23:00` — Debug lazy code\n* `24:20` — Add completions to UI\n* `25:18` — Load data in a functional way\n* `28:30` — Improve performance of the data loading\n* `33:20` — Improve the UI responsiveness in RX style\n* `40:05` — Using [Kovenant](https://github.com/mplatvoet/kovenant) library\n* `42:03` — Using [funKTionale](https://github.com/MarioAriasC/funKTionale) library\n* `44:10` — Currying\n* `45:35` — Questions\n\nAbout the Presenter:\n\n![Mike Hearn](http://i2.wp.com/info.jetbrains.com/rs/426-QVD-114/images/Mike_Hearn_200x200.jpg?resize=100%2C100 \"Mike Hearn\") [Mike Hearn](http://plan99.net/~mike/) is a Java, Kotlin and C++ developer who works on digital currency related software. Prior to that he was a senior software engineer at Google, where he spent over seven years working on a range of products including Earth, Maps, Gmail and the accounts system.\n\nThanks to all the attendees for the questions! If you still have some, please, contact Mike or our team.\n\nYou are welcome to suggest themes for future webinars in comments.\n\n_Let’s kotlin!_\n","author":"Roman Belov","date":"2015-11-05","type":"webinar","categories":["Kotlin","Webinar","Fp","Functional"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"I wrote my website in Kotlin","url":"https://medium.com/lewisrhine/i-wrote-my-website-in-kotlin-cc55263d2028#.k20k8snpp","body":"\nA few weeks ago I thought I should have a [website](http://lewisrhine.com/). Since I am an Android developer, I thought it should be in material design and because I’m a full on fanboy lunatic I thought it should be written on Kotlin.\n\nIf you didn’t know Kotlin can also compile to JavaScript. It’s still experimental but Jetbrain has said they are still committed to it. It’s something we should care about. In case you haven’t noticed JavaScript is taking over the world. While there are plenty of other JavaScript transpilers, if React Native gets as big as it seems I would rather write it in Kotlin over JavaScript.\n\nFor my site, Google’s [Material Design Lite](https://getmdl.io/) seemed like the easiest way to do it.\n\nI whipped up a quick single page front-end framework named Kotlin Material Design Lite… Yeah, I know a boring name. The docs on Kotlin-JavaScript are slim, to say the least. So there is a good chance there are better methods than the ones I came up. It’s also very much not complete. It mostly just has the components I needed. But I do plan to keep working on it and any other contributions are welcome. If nothing else, it is a great way to learn more about Kotlin-JavaScript and be ready for when the tide of JavaScript drowns us all.\n\nThere are three main parts to KMDL.\n\n```kotlin\nfun mdlApp(init: MdlApp.() -> Unit): MdlApp {\n val app = MdlApp()\n app.init()\n return app\n}\n\nclass MdlApp() {\n private val app = document.getElementById(\"MdlApp\")\n\n init {\n requireNotNull(app) { \"No MldApp Element found!\" }\n }\n\n fun navigationLayout(content: MdlContent, cssClass: String = \"\", init: Layout.() -> Unit) {\n val nl = Layout(content, cssClass)\n nl.init()\n nl.mainElement.append(nl.content.content.mainElement)\n app?.append(nl.mainElement)\n }\n}\n```\n\nThis class looks for a div with an id of “MdlApp”. In Kotlin-JavaScript you interact with the DOM using “document” so when I call “document.getElementById(“MdlApp”)” it searches the HTML for an element with the id of MdlApp and returns it or null if it doesn’t find it.\n\nThe other main part is an abstract class MdlComponent. It’s what’s used to build out all the Material Design Lite Components.\n\n```kotlin\nabstract class MdlComponent(tag: String, classType: String, cssClassId: String = \"\") {\n val mainElement = document.createElement(tag).apply { this classType \"$cssClassId $classType\" }\n\n var backgroundColor: MdlColor.Background? = null\n set(value) {\n value?.let { mainElement.setAttribute(\"class\", mainElement.getAttribute(\"class\")?.plus(\" $it\")!!) }\n }\n\n var textColor: MdlColor.Text? = null\n set(value) {\n value?.let { mainElement.setAttribute(\"class\", mainElement.getAttribute(\"class\")?.plus(\" $it\")!!) }\n }\n\n fun htmlPram(parent: Element = mainElement): ReadWriteProperty = object : ReadWriteProperty {\n private var prop: T? = null\n\n override fun getValue(thisRef: Any, property: KProperty<*>): T {\n return prop ?: throw IllegalStateException(\"Property ${property.name} should be initialized before get.\")\n }\n\n override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {\n prop = value\n set(property.name, prop!!)\n }\n\n private fun set(name: String, value: T) {\n parent.setAttribute(name, \"$value\")\n if (name == \"href\") parent.setAttribute(\"target\" ,\"_blank\")\n }\n }\n\n fun htmlTextPram(text: String = \"\", parent: Element = mainElement): ReadWriteProperty = object : ReadWriteProperty {\n private var prop: String = text\n\n init {\n set(prop)\n }\n\n override fun getValue(thisRef: Any, property: KProperty<*>): String = prop\n\n override fun setValue(thisRef: Any, property: KProperty<*>, value: String) {\n prop = value\n set(prop)\n }\n\n private fun set(text: String) {\n parent.textContent = text\n }\n }\n\n fun appendToMain(initItem: T) = object : ReadWriteProperty {\n var item = initItem\n\n init {\n mainElement.append(item.mainElement)\n }\n\n override fun getValue(thisRef: Any, property: KProperty<*>): T = item\n\n override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {\n mainElement.append(value.mainElement)\n item = value\n }\n }\n\n fun appendToMainIf(condition: Boolean, initItem: T) = object : ReadWriteProperty {\n var item = initItem\n\n init {\n if (condition) mainElement.append(item.mainElement)\n }\n\n override fun getValue(thisRef: Any, property: KProperty<*>): T = item\n\n override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {\n if (condition) {\n mainElement.append(value.mainElement)\n item = value\n }\n }\n }\n\n operator fun Element.unaryPlus() {\n mainElement.append(this)\n }\n}\n```\n\ndocument.createElement is how Kotlin-JavaScript creates elements on the DOM. This class also makes heavy use of delegate properties to make creating the components attributes easier. For example the Img\n\n```kotlin\nclass Img(cssClassId: String = \"\") : MdlComponent(\"img\", cssClassId) {\n var src: String by htmlPram()\n var width: Int by htmlPram()\n var height: Int by htmlPram()\n var border:Int by htmlPram()\n var alt: String by htmlPram()\n}\n\n```\n\nThe src property uses the htmlPram delegate which uses the property’s name to set HTML attributes.\n\nNow inside the main function just build out a MdlApp using the mdlApp function.\n\n```kotlin\nfun main(args: Array) {\n val mdlApp = mdlApp {\n navigationLayout(About, \"layout\") {\n header {}\n drawer(\"drawer\") {\n mainElement.header(\"drawer-header ${MdlColor.Background.blueGrey(Shade.s300)}\") {\n img(\"avatar\") { src = \"images/roundprofile.png\" }\n b { textContent = \"Lewis Rhine\" }\n append(document.createTextNode(\"Android Developer\"))\n }\n\n nav(\"navigation\") {\n link { text = \"About\"; materialIcons = \"account_circle\"; onClick { content = About } }\n link { text = \"Blog\"; materialIcons = \"book\"; href = \"https://medium.com/lewisrhine\" }\n link { text = \"Projects\"; materialIcons = \"build\"; href = \"https://github.com/lewisrhine\" }\n link {\n text = \"Twitter\"\n href = \"https://twitter.com/lewisrhine\"\n mainElement.append(document.createElement(\"i\").apply {\n setAttribute(\"class\", \"material-icons fa fa-twitter\")\n })\n }\n link {\n text = \"Instagram\"\n href = \"https://www.instagram.com/lewisrhine\"\n mainElement.append(document.createElement(\"i\").apply {\n setAttribute(\"class\", \"material-icons fa fa-instagram\")\n })\n }\n link {\n text = \"LinkedIn\"\n href = \"https://www.linkedin.com/in/lewisrhine\"\n mainElement.append(document.createElement(\"i\").apply {\n setAttribute(\"class\", \"material-icons fa fa-linkedin\")\n })\n }\n link { text = \"email\"; href = \"mailto:lewisrhine@gmail.com\"; materialIcons = \"email\" }\n }\n }\n }\n }\n}\n```\n\nThe last part is the MdlContent.\n\n```kotlin\nfun content(title: String, cssClassId: String = \"\", body: Element.() -> Unit) = Content(title, cssClassId, body)\n\nclass Content(val title: String, cssClassId: String = \"\", body: Element.() -> Unit) : MdlComponent(\"div\", \"mdl-layout__content\", cssClassId) {\n init {\n mainElement.body()\n }\n}\n\ninterface MdlContent {\n val content: Content\n}\n```\n\nIt’s used to build out content pages for the app.\n\n```kotlin\nobject About : MdlContent {\n override val content = content(\"About\") {\n setAttribute(\"style\", \" background: url('images/whoiam.jpg') center / cover; filter: alpha(opacity=60); padding: 10px;\")\n\n grid {\n cell(3) {}\n\n cellCard(6) {\n title = \"About me\"\n supportingText = \"Completely self-taught, I began my love for writing code when I was you kid and found out about QBasic on the family computer. In my day to day life, I enjoy keeping up with new developments within the technology and android community. I am very passionate about clean thought out architecture in the code I write. And believe strongly in testing as much as possible. Even on Android where it's not the easiest to accomplish.\"\n }\n\n cell(3) {}\n\n cell(1) {}\n cell(10) {\n chip(contact = true) { src = \"images/java-logo.png\"; text = \"Java\" }\n chip(contact = true) { src = \"images/kotlin-logo.png\"; text = \"Kotlin\" }\n chip(contact = true) { src = \"images/android-logo.png\"; text = \"Android Native\" }\n chip(contact = true) { src = \"images/rxjava-logo.png\"; text = \"RxJava\" }\n chip(contact = true) { src = \"images/javascript-logo.png\"; text = \"JavaScript\" }\n chip(contact = true) { src = \"images/react-logo.png\"; text = \"React Native\" }\n chip(contact = true) { src = \"images/unity-logo.png\"; text = \"Unity3D\" }\n chip { text = \"Junit\" }\n chip(contact = true) { src = \"images/mockito-logo.png\"; text = \"Mockito\" }\n }\n cell(1) {}\n\n cellCard(4) {\n\n size()\n title = \"Rithmio\"\n supportingText = \"Mar 2016 — present\"\n mainElement.list {\n item(ListIem(\"-At Rithmio I Introduced new technologies like Kotlin and RxJava which have helped to make the team faster and more efficient.\"))\n item(ListIem(\"-Rithmio EDGE: I designed a new architecture based on Flux style circular data streams that made the code base more testable and stable.\"))\n item(ListIem(\"-Cadence Counter: I built a prototype app from the ground up that had a strict two-week window of completion. I was able to complete it in only a week giving the project an extra week for testing. \"))\n }\n\n }\n\n cellCard(4) {\n size()\n title = \"MeetBall\"\n supportingText = \"Jun 2015 — Mar 2016\"\n mainElement.list {\n item(ListIem(\"-At MeetBall I was the sole Android developer took over code base from a contractor and quickly moved the code a more structured testable state.\"))\n item(ListIem(\"-Integrated Beacon awareness into the app using the Radius Networks SDK\"))\n }\n }\n\n cellCard(4) {\n title = \"Tinker Entertainment\"\n supportingText = \"Sep 2014 — Nov 2014\"\n mainElement.list {\n item(ListIem(\"While defunct, I picked up this project for my friend’s new company venture when his original developer dropped out. With the game’s code base written in C# and using the Unity3D framework, I quickly adapted myself to the language and provided an initial product release.\"))\n }\n }\n }\n }\n}\n```\n\nAgain the project, like Kotlin-JavaScript is still experimental but you can take a look at the code and you want to contribute [here](https://github.com/LewisRhine/Kotlin-Material-Design-Lite).\n\n","author":"Lewis Rhine","date":"2017-01-05","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Algebraic Data Types In Kotlin","url":"http://engineering.pivotal.io/post/algebraic-data-types-in-kotlin/","body":"\n\nLately I have been doing a good amount of reading on functional programming, specifically [Haskell](http://haskellbook.com/) and [Elm](http://elm-lang.org/). As part of this reading, I've been exposed to the wonderful world of type systems more advanced than the ones that I am used to, i.e. the Java type system. Exposure to [algebraic data types (ADTs)](https://en.wikipedia.org/wiki/Algebraic_data_type) is one of the things that I've enjoyed about these readings. In the rest of this article, I will demonstrate how ADTs can be used in the Kotlin type system to assure that you've handled all of the possible outcomes from a business use case. For those already familiar with the [`Either` type](https://hackage.haskell.org/package/base-4.8.2.0/docs/Data-Either.html) much of this will be old news to you.\n\nAlgebraic data types allow me to create a closed set of possible options for a specific type in my domain.\n\n```kotlin\nsealed class CreateSubscriptionResult {\n class Success(val subscription: Subscription): CreateSubscriptionResult()\n class Failure(val errors: List): CreateSubscriptionResult()\n}\n```\n\nIn this case I am using the [`sealed` keyword](https://kotlinlang.org/docs/reference/classes.html#sealed-classes) to tell the type system that there will not be any more possible outcomes for a `CreateSubscriptionResult`. Now I can use the `when` keyword to force the consumer of the `CreateSubscriptionResult` to make sure it handles all of the possible outcomes.\n\n```kotlin\nreturn when (result) {\n is CreateSubscriptionResult.Success ->\n // Do something on success\n is CreateSubscriptionResult.Failure ->\n // Do something on failure\n}\n```\n\nWere I to omit one of the possible outcomes,\n\n```kotlin\nreturn when (result) {\n is CreateSubscriptionResult.Success ->\n // Do something on success\n}\n```\n\nthen the Kotlin compiler will tell me that I've forgotten something.\n\n```\nwhen expression must be exhaustive, add necessary 'is Failure' branch or 'else' branch instead\n```\n\nWell isn't that nice. I now can use the type system to remind myself, and my fellow developers, that something is missing and keep those types of bugs from cropping up in my software without a lot of boilerplate code. If another outcome is added at some point, the compiler will tell me that and I can then figure out how to handle it.\n\nBy using the type system to do this, I enable a faster feedback loop than had I written a test for it. Yes I may still need a test for the logic inside of each branch but I would postulate that if I keep it simple enough (like a difference in response code) that a test may be overkill because of the type system assurance. I'll leave that decision up to you.\n\nOne place I have been experimenting with this type of pattern is in my [Spring controllers](https://github.com/mikegehard/user-management-evolution-kotlin/blob/master/applications/ums/src/main/kotlin/com/example/ums/subscriptions/SubscriptionsController.kt#L36-L47). I like how it makes the code that handles the outcomes easy to read and understand. Another benefit is that I now have an explicit contract between the use case and the consumer that outlines all of the possible outcomes for the use case. When I combine this contract with the `when` keyword, the compiler will enforce that the client either handles each outcome or decides to explicitly punt on some by using the `else` keyword.\n\nHave some feedback? I'd love to hear it. Reach out to me on Twitter @mikegehard and we can have a conversation about it.\n\n","author":"Mike Gehard","date":"2016-03-19","type":"article","categories":["Kotlin","Functional Programming"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin is cheating on me...","url":"https://hackernoon.com/kotlin-is-cheating-on-me-e048cde4f66#.5vq8chhbz","body":"\n## ... but I’m OK with it.\n\nEarlier this month, I published an account of my very first experience of Android development. It wasn’t pretty.\n\n[**Android is hard** _TL;DR. I have my very first Android app out!_ hackernoon.com](https://hackernoon.com/android-is-hard-b7a5a5549655)\n\nBeing honest pays, and in this case it paid so much that one of the editors at Hackernoon picked my story up, and then some. Numbers were shooting up, I could not be happier. Then something happened.\n\nYou know when you are aimlessly complaining about X on the Internet, and some guy shows up and says “Why don’t you use Y?” Question mark, that’s it. I hate this kind of comments. No evidence for why Y is better than X or why Y — oh, why — would make my life any less miserable. To be fair, pretty much anything is guaranteed to make your life less miserable than Java, so I said what the heck, and tried my luck with Kotlin.\n\nI heard good things about Kotlin, you know, like how it is null-safe, and Java is not, and that is the premier source of bemusement of roughly 99.9% of the people who ever used anything that could run Java.\n\n![](https://cdn-images-1.medium.com/max/800/1*UzblnQYcfXEZlg37__zxWw.png)\n\nWhen you see it...\n\nKotlin has many other nice features, but I was sold at null-safety. Kotlin is also developed by the nice people at JetBrains, who happen to be the same that develop IntelliJ IDEA, the IDE on which Android Studio is based. With the most amazing of _non sequuntur_, Android Studio has an automatic get-Java-the-hell-out-of-my-life plugin that turns your Java code into Kotlin. I haven’t tested it extensively, but it worked very well for me. Granted, it left behind a number of Javaisms, but they were pretty easy to fix.\n\nTo make a long story short, I hit “make it so” to run my app on my phone. I have been around programming long enough that I was not expecting this to work, and yet it did. Within seconds, I had to ask the Internet how to check whether my Kotlin app was really running, or my phone was running the Ghost of Apps Past. After some digging, it suddenly hit me: Kotlin is not only compiled to JVM bytecode, but it also effectively uses much of Java’s and Android’s regular libraries. That makes perfect sense. It’s almost as if Kotlin code is getting transpiled — yes, that’s a word — to Java, and then a regular old boring Java compiler is used, except that it isn’t, it’s much more clever than that, and that’s all that matters.\n\nOn the other hand, Kotlin is effectively lying to me. Whenever I declare a Map, and initialise it with a `mapOf()`, what happens is that I’m given a cleverly disguised `LinkedHashMap`, and that is what you end up using in your code: a regular, old `LinkedHashMap` with all its quirks and methods. Don’t get me wrong, Kotlin is a nice language, but the more I dove into making sure that my newly-converted code still made sense, the more the feeling that I was being cheated grew. In the end, I’m still writing an Android app, and everything is written in Java, and that means that there is an awful lot of things that can be null at runtime. Sure, Kotlin has ways of dealing with that, and very nice ways at that, but I found myself having to use them way more often than I was expecting. To make things worse, there is practically no way of telling in advance what values may be null at runtime, because the Java codebase is so poorly annotated, and so the best advice I got was to always assume that everything that touches Java can be null at any time.\n\nThe single reason for me to switch to Kotlin, vaporised. I let that sink in for a moment...\n\n... and then I still got on with Kotlin because overall it’s a much nicer language to look at.\n\nFor those who are wondering, “_non sequuntur_” is the correct plural of “_non sequitur_”. Get your Latin straight, you Anglophones.\n\n","author":"Andrea Franceschini","date":"2016-12-24","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"A Geospatial Messenger with Kotlin, Spring Boot and PostgreSQL","url":"https://spring.io/blog/2016/03/20/a-geospatial-messenger-with-kotlin-spring-boot-and-postgresql","body":"\n\nFollowing my first [Kotlin blog post](https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin), today I want introduce the new Spring Boot + Kotlin application I have developed for my upcoming [Spring I/O 2016 conference](http://www.springio.net/) talk “Developing Geospatial Web Services with Kotlin and Spring Boot”.\n\n# Dealing with native database functionalities\n\nOne of the goal of this application is to see how to take advantage of native database functionalities like we do in NoSQL world. Here we want to use Geospatial support provided by [PostGIS](http://postgis.net/), the spatial database extender for [PostgreSQL](http://postgresql.org/). [Native JSON support](https://www.compose.io/articles/is-postgresql-your-next-json-database/) could also be a good use case.\n\nThis Geospatial Messenger sample application is [available on GitHub](https://github.com/sdeleuze/geospatial-messenger) in 2 flavors:\n- The `master` branch uses [Exposed](https://github.com/JetBrains/Exposed), a Kotlin SQL library with a typesafe API created by JetBrains. It could be compared to [Query DSL SQL](https://github.com/querydsl/querydsl/tree/master/querydsl-sql) or [jOOQ](http://www.jooq.org/) but provides an idiomatic Kotlin API and does not require code generation.\n- The [`spring-data-jdbc-repository`](https://github.com/sdeleuze/geospatial-messenger/tree/spring-data-jdbc-repository) branch is using `spring-data-jdbc-repository`, a community project that allows to use Spring Data [`PagingAndSortingRepository`](https://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/repository/PagingAndSortingRepository.html) API with raw SQL queries without JPA. I am using [this Jakub Jirutka fork](https://github.com/jirutka/spring-data-jdbc-repository/) which is an improved version of [Tomasz Nurkiewicz original project](https://github.com/nurkiewicz/spring-data-jdbc-repository).\n\nA [Spring Data JPA + Hibernate Spatial variant](https://github.com/sebastianperruolo/spring-gis) would be interesting, so feel free to contribute it with a pull request ;-) Kotlin Query DSL support would be also nice but this is currently not supported (please comment on [this issue](https://github.com/querydsl/querydsl/issues/1828) if you are interested). In this blog post I will focus on the [Exposed](https://github.com/JetBrains/Exposed) variant.\n\n# A tour of Geospatial Messenger code\n\nOur domain model is described easily thanks to these 2 [Kotlin data classes](https://kotlinlang.org/docs/reference/data-classes.html):\n\n```kotlin\ndata class Message(\n var content : String,\n var author : String,\n var location : Point? = null,\n var id : Int? = null\n)\n\ndata class User(\n var userName : String,\n var firstName : String,\n var lastName : String,\n var location : Point? = null\n)\n```\n\nExposed allows us to describe the structure of our tables with a type-safe SQL API quite handy to use (autocomplete, refactoring and error prone):\n\n```kotlin\n object Messages : Table() {\n val id = integer(\"id\").autoIncrement().primaryKey()\n val content = text(\"content\")\n val author = reference(\"author\", Users.userName)\n val location = point(\"location\").nullable()\n }\n\n object Users : Table() {\n val userName = text(\"user_name\").primaryKey()\n val firstName = text(\"first_name\")\n val lastName = text(\"last_name\")\n val location = point(\"location\").nullable()\n }\n```\n\nIt is interesting to notice that Exposed does not support natively PostGIS functionalities like geometry types or geospatial requests. That’s where [Kotlin extensions](https://kotlinlang.org/docs/reference/extensions.html) shine, and allow with a few lines of code to add such support without requiring to use extended classes:\n\n```kotlin\nfun Table.point(name: String, srid: Int = 4326): Column\n = registerColumn(name, PointColumnType())\n\ninfix fun ExpressionWithColumnType<*>.within(box: PGbox2d) : Op\n = WithinOp(this, box)\n```\n\nOur repository is also quite short and very flexible, since it allows you to write any kind of SQL request even with complex `WHERE` clause with a type-safe SQL API. Currently we need to use `db.transaction{ }` wrapper, I have created Exposed issue [#25](https://github.com/JetBrains/Exposed/issues/25) to be able to use regular [Spring transaction management](http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html) with [`@Transactional`](http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations) annotation, feel free to add your +1 ;-)\n\nPlease notice that since we are using Spring Framework 4.3, we [no longer need to specify an `@Autowired` annotation in such single-constructor class](https://spring.io/blog/2016/03/04/core-container-refinements-in-spring-framework-4-3#implicit-constructor-injection-for-single-constructor-scenarios).\n\n```kotlin\n@Repository\nopen class UserRepository(val db: Database) {\n\n open fun createTable() = db.transaction {\n create(Users)\n }\n\n open fun create(user: User) = db.transaction {\n Users.insert( toRow(user) )\n }\n\n open fun updateLocation(u:String, l: Point) = db.transaction {\n location.srid = 4326\n Users.update({Users.userName eq u}) { it[Users.location] = l}\n }\n\n open fun findAll() = db.transaction {\n Users.selectAll().map { fromRow(it) }\n }\n\n open fun findByBoundingBox(box: PGbox2d) = db.transaction {\n Users.select { Users.location within box }.map { fromRow(it) }\n }\n\n open fun deleteAll() = db.transaction {\n Users.deleteAll()\n }\n\n fun toRow(u: User): Users.(UpdateBuilder<*>) -> Unit = {\n it[userName] = u.userName\n it[firstName] = u.firstName\n it[lastName] = u.lastName\n it[location] = u.location\n }\n\n fun fromRow(r: ResultRow) =\n User(r[Users.userName],\n r[Users.firstName],\n r[Users.lastName],\n r[Users.location])\n}\n```\n\nControllers are also very concise and use Spring Framework 4.3 upcoming `@GetMapping` / `@PostMapping` annotations which are just method-specific shortcuts for `@RequestMapping` annotations:\n\n```kotlin\n @RestController\n @RequestMapping(\"/user\")\n class UserController(val repo: UserRepository) {\n\n @PostMapping\n @ResponseStatus(CREATED)\n fun create(@RequestBody u: User) { repo.create(u) }\n\n @GetMapping\n fun list() = repo.findAll()\n\n @GetMapping(\"/bbox/{xMin},{yMin},{xMax},{yMax}\")\n fun findByBoundingBox(@PathVariable xMin:Double,\n @PathVariable yMin:Double,\n @PathVariable xMax:Double,\n @PathVariable yMax:Double)\n = repo.findByBoundingBox(\n PGbox2d(Point(xMin, yMin), Point(xMax, yMax)))\n\n @PutMapping(\"/{userName}/location/{x},{y}\")\n @ResponseStatus(NO_CONTENT)\n fun updateLocation(@PathVariable userName:String,\n @PathVariable x: Double,\n @PathVariable y: Double)\n = repo.updateLocation(userName, Point(x, y))\n }\n```\n\nThe client side is a pure HTML + Javascript application developed with [OpenLayers](http://openlayers.org/) mapping library (see [index.html](https://github.com/sdeleuze/geospatial-messenger/blob/master/src/main/resources/static/index.html) and [map.js](https://github.com/sdeleuze/geospatial-messenger/blob/master/src/main/resources/static/map.js) for more details) that geolocalizes you and creates geolocalized messages sent/received to/from other users thanks to Server-Sent Events.\n\n![Screenshot](https://raw.githubusercontent.com/sdeleuze/geospatial-messenger/master/screenshot.png)\n\nAnd last but not least, the REST API is fully tested and documented thanks to the awesome [Spring REST docs](http://projects.spring.io/spring-restdocs/) project, see [MessageControllerTests](https://github.com/sdeleuze/geospatial-messenger/blob/master/src/test/kotlin/io/spring/messenger/MessageControllerTests.kt) and [index.adoc](https://github.com/sdeleuze/geospatial-messenger/blob/master/src/main/resources/static/index.html) for more details.\n\n# Conclusion\n\nThe main impression I had developing this application is that it was fun, efficient, with a high level of flexibility and safety provided by the SQL API and Kotlin type system and [null safety](https://kotlinlang.org/docs/reference/null-safety.html). The resulting Spring Boot application is a 18 MBytes self-contained executable jar with low memory consumption (the app can run with `-Xmx32m`!!!). Using Spring REST docs was also a pleasure, demonstrating again Kotlin nice Java interoperability.\n\nThe few pain points I have encountered ([array annotation attributes](https://youtrack.jetbrains.com/issue/KT-11235), [Java 8 Stream support](https://youtrack.jetbrains.com/issue/KT-5175), [full callable reference support](https://youtrack.jetbrains.com/issue/KT-6947)), are planned to be fixed in Kotlin 1.1. Exposed library is still young and need to mature, but from my point of view it is promising and shows how Kotlin could be used for building type-safe DSL API ([this HTML type-safe builder](https://kotlinlang.org/docs/reference/type-safe-builders.html) is also a good example).\n\nAnd keep in mind that officially supported [Spring Data projects](http://projects.spring.io/spring-data/) works well with Kotlin as shown in the [spring-boot-kotlin-demo](https://github.com/sdeleuze/spring-boot-kotlin-demo) project in my [previous blog post](https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin).\n\nIf you happen to be in Barcelona mid May (never a bad time to be in Barcelona anyway!), don’t miss the chance to join the [Spring I/O conference](http://www.springio.net/). Also, the registration for [SpringOne Platform](http://springoneplatform.io/) (early August, Las Vegas) has opened recently, in case you want to benefit from early bird ticket pricing. The latter is also still open for talk proposals. So if you’re interested to give a talk about Spring or Pivotal-related technologies, feel free to submit!\n\n","author":"Sébastien Deleuze","date":"2016-03-20","type":"article","categories":["Kotlin","Spring"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Using Kotlin type-safe builders to create a DSL for Forms","url":"https://engineering.facile.it/blog/eng/kotlin-dsl/","body":"\nHere at Facile.it we are constantly dealing with a lot of **forms**: we use them to collect various information and data needed to feed our in-house comparing algorithms. These forms could be **really complex**, having multiple rules and dependencies between fields, and they are likely to be **changed and tuned frequently**.\n\nWhen I joined Facile.it, a lot of forms within the Android app needed to be updated or modified and sticking with the existing strategy would have required me to do **a lot of work** just to add or remove a simple field. So I took a step back and I started thinking about a strategy that would have allowed me to define and structure a form in a more *flexible* and *declarative* way. I wanted to be able to declare the **relationships** between fields, their **validation rules** and their **serialized representation** (how they are sent to the server).\n\nI firstly thought about defining it using some configuration file, maybe written in JSON or YAML. The *problem* with this strategy was that it would also have required me to write a lot code to parse and validate those files to be able to create some sort of representation of the form in Java…but don’t we already have the compiler for this kind of jobs?\n\nI still wanted to be able to have both a **human readable representation** of the form and the right degree of **flexibility** to integrate the form definition into the app code. So I thought that creating a [Domain-Specific Language](https://en.wikipedia.org/wiki/Domain-specific_language) would have been a perfect strategy to solve the problem in an elegant and efficient way. Writing a DSL in Java could have ended up into something like that:\n\n```kotlin\nForm.create()\n .openSection(sectionId)\n .field(key1, \"label1\", style, ...)\n .field(key2, \"label2\", style, ...)\n .field(key3, \"label3\", style, ...)\n .closeSection()\n ...\n .build()\n```\n\nI don’t think the previous code is readable nor flexible and it requires a lot of boilerplate to be written.\n\n## Kotlin to the rescue! ##\n\nUnlike Java, Kotlin (take a look at my [previous post](https://engineering.facile.it/blog/eng/kotlin-intro/) about it) has a lot of features that makes it really powerful when it comes to write internal DSLs. The results are very similar to Groovy (think about a Gradle file) but thanks to its type system they could be [Type-Safe](https://kotlinlang.org/docs/reference/type-safe-builders.html#type-safe-builders).\n\nThe builders you can write with Kotlin are extremely readable and easy to understand even for people that don’t know either the language or the DSL itself. Here’s how a form built using my final DSL looks like:\n\n```kotlin\nval FORM = form {\n page(\"Page 1 Title\") {\n section(\"Section 1 Title\") {\n field(key = \"fieldKey1\") {\n checkbox(\"Checkbox Field Label\") {\n boolToStringConverter = { if (it == true) \"Yes\" else \"No\" }\n rules = { listOf(NotMissing()) }\n }\n }\n field(key = \"fieldKey2\") {\n picker(\"Picker Field Label\") {\n placeHolder = \"Select a value\"\n possibleValues = Available(listOf(\n 1 keyTo \"Value1\",\n 2 keyTo \"Value2\",\n 3 keyTo \"Value3\"))\n representation = IF_VISIBLE representAs SIMPLE_KEY_TO_VALUE\n }\n }\n }\n section(\"Section 2 Title\") {\n field(key = \"fieldKey3\") {\n picker(\"Picker Field Label\") {\n placeHolder = \"Select a value\"\n possibleValues = ToBeRetrieved(someWebService.getValues())\n representation = IF_VISIBLE representAs SIMPLE_KEY_TO_VALUE\n }\n }\n field(key = \"fieldKey4\") {\n input(\"Input Text Field Label\") {\n inputTextType = InputTextType.EMAIL\n rules = { listOf(IsEmail()) }\n }\n }\n field(key = \"fieldKey\") {\n empty(\"Empty Field\")\n }\n }\n section(\"Section 3 Title\") {\n field(key = \"fieldKey6\") {\n toggle(\"Toggle Field Label\") {\n boolToStringConverter = { if (it == true) \"OK\" else \"KO\" }\n rules = { listOf(NotMissing()) }\n representation = ALWAYS representAs SIMPLE_KEY_TO_VALUE\n }\n }\n }\n }\n}\n```\n\n\nAnd this is the result on Android using my [Form library](https://github.com/brescia123/forms):\n\n![Form screenshot](https://engineering.facile.it/images/kotlin-dsl/form_screen.png)\n\nCool, isn’t it?\n\n## Type-safe builders ##\n\n### Some Kotlin important features ###\n\nTo grasp how Type-safe builders work in Kotlin we need to understand some key Kotlin features and how they can be combined together:\n\n * **Higher-Order Functions and Lambdas**: in Kotlin we are allowed to write functions that have *functions as parameters or return type* (higher-order functions) and functions that are *not declared*, but are passed immediately as an expression (lambdas). Because of this, we can write things like:\n\n```kotlin\n// Higher-Order Function\nfun transformWith(path: String, function: (String) -> List): List {\n return function(this)\n}\n\n// Lambda\n{ path: String -> path.split(\"/\") }\n```\n\nThanks to Kotlin syntactic sugar we can use them in these ways:\n\n```kotlin\ntransformWith(\"some/path/to\", { path: String -> path.split(\"/\") }) // -> [some, path, to]\n\n// Functions which have a function as the last parameter can be written as follow\ntransformWith(\"some/path/to\") { path -> path.split(\"/\") } // -> [some, path, to]\n\n// If the lambda has only one parameter it can be ommitted and referenced as \"it\"\ntransformWith(\"some/path/to\") { it.split(\"/\") } // -> [some, path, to]\n```\n\n * **Extension Functions**: they allow us to *extend* a type with functions without modifying the original class. They are useful to add functionalities to classes we don’t have control on or to create utility methods without the need to create “Utils classes” that contains static methods, as we are used to as Java developers. To continue the previous example we can write:\n\n```kotlin\n// Extension function\nfun String.transformWith(function: (String) -> List) {\n return function(this)\n}\n\n\"some/path/to\".transformWith { receiverString: String -> receiverString(\"/\") } // -> [some, path, to]\n\n// or more concisely\n\"some/path/to\".transformWith { it.split(\"/\") } // -> [some, path, to]\n```\n\nNote that we are referring to the string inside the closure of the extension function using `this` as it will be the String object on which the method will be called.\n\n * **Function Literals with Receiver**: similarly to extension functions you are also allowed to define functions with a receiver that will be referred to as `this` inside the literal closure:\n\n```kotlin\nval transformWith: String.() -> List = { this.split(\"/\") }\n\n\"some/path/to\".transformWith() // -> [some, path, to]\n```\n\nTo better understand function literals with receiver you should think of them as follow: *lambda is to normal function as function literal with receiver is to extension function*.\n\n```kotlin\n// lambda\n{ s: String -> s.split(\"/\") }\n// is to\nfun function(s: String): List { return s.split(\"/\") }\n// as\nval functionLiteralWithReceiver = String.() -> List = { this.split(\"/\") }\n// is to\nfun String.extensionFunction(): List { return function(this) }\n```\n\nBasically function literals with receiver are extension functions that can be passed to other functions.\n\n### Wrapping up ###\n\nNow we have all the elements required to understand and write a Type-safe builder.\n\nCombining the above mentioned Kotlin features we can now write a function and name it `form`. This function will take as parameter a function literal with receiver usually called `init()` and will do the follow:\n\n * create a new Form object\n * call `init()` on it (that is using it as the receiver of the function literal)\n * return the built object to the caller\n\n```kotlin\nfun form(init: Form.() -> Unit): Form {\n val form = Form()\n form.init()\n return form\n}\n```\n\nNow let’s imagine that our Form class defines a function `field()` that actually creates a field object and adds it to the list of fields contained within the form:\n\n```kotlin\nclass Form() {\n val fields: List\n ...\n fun field(key: String) { ... }\n ...\n}\n```\n\nTaking advantage of Kotlin syntactic sugar we can use `form()` passing it the `init()` function as a lambda and call methods on the Form object to build it as follow:\n\n```kotlin\nval builtForm = form() {\n // Here we can take advantage of the compiler and, as a result, of the IDE code completion\n field(\"key1\") // == this.field(\"key1\") where this is the object create by form()\n field(\"key2\")\n}\nbuiltForm.getFields() // -> [Field(\"key1\"), Field(\"key2\")]\n```\n\nAs you can see Type-Safe builders are an **extremely powerful** and useful feature of Kotlin and they allow you to write very complex DSLs with a **really readable and clear syntax**. They give you a lot of **flexibility** letting you combine multiple builders to create a domain language that can meet your requirements.\n\nIf you want to learn more about this subject check out the official [documentation](https://github.com/Kotlin/kotlinx.html) or, for example, [kotlinx](https://github.com/Kotlin/kotlinx.html), an official project from the Kotlin team that allows you to create HTML documents with a custom DSL entirely written with Type-safe builders.\n","author":"Giacomo Bresciani","date":"2017-02-08","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"JVMLS 2015 - Flexible Types in Kotlin","url":"https://www.youtube.com/watch?v=2IhT8HACc2E","body":"\n\n\n\n","author":"Andrey Breslav","date":"2015-08-12","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin: How to Make Your Java Code Base Cleaner and More Readable","url":"https://medium.com/@kford55/kotlin-why-i-feel-its-useful-in-a-java-only-code-base-206bdb37c79#.4jgdz27kr","body":"\nTLDR;\n\nKotlin is a JVM language developed by JetBrains that compiles to Java 6 Bytecode. It is interoperable with Java and allows you to work with both languages in the same project. It lets you take advantage of a lot of great features in a legacy code base, such as lambdas, filters and streams, null safety, and top class IDE support as well. [https://kotlinlang.org](https://kotlinlang.org/)\n\nThis post was inspired by Brent Watson’s ([@brent_watson](https://twitter.com/brent_watson)) presentation at the last New York Android Developers meetup at Facebook where he talked about changing the I/O schedule app into Kotlin. Although most of the talks and articles about Kotlin have been in an Android context, it can still be useful in a regular java environment.\n\nKotlin is a JVM Language built by JetBrains, the same people who make IntelliJ. It was unveiled in 2011 but really starting to pick up traction now, mainly from the Android community. This is for a couple of reasons, first is up until Android 7 you had to use Java 7. If you wanted to get some of the features of Java 8 you had to use third-party libraries such as Retrolambda. The other reason is that it’s a very small library, so you put very little pressure on the method count limit for being a single DEX app. (~65k public methods) Using Kotlin for Android lets you do things like lambdas, higher-order functions, streams and have null safety in your app.\n\nSo why am I writing about it when I work in mainly a non-mobile environment? Because it’s interesting to me and there are a lot of people who are using it within regular Java code as well!\n\nTo start let’s talk about tools. Without tools, languages or libraries overall are useless and won’t get used. Luckily for us! Kotlin was built by JetBrains. The good part about deciding to use Kotlin is that you can do it one file at a time. [Brent](https://twitter.com/brent_watson) talked about how they transitioned their Android app to Kotlin, and they started by converting Unit Tests to Kotlin and then with real source code. It’s very easy to start messing around and using Kotlin. The best part is you don’t have to do anything to convert these files! (Well maybe a little bit)\n\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*ETOr2IP8cjeHohYpi-zYHQ.png)\n\n_IntelliJ’s tool to convert Java files to Kotlin_\n\nCommand-Shift-A, Convert Java File to Kotlin File, and you’re done! It converts everything into working Kotlin code unless you’re using some libraries and frameworks then you’ll have to take a minute and mess around with some things. Either way, it’s still very quick and painless. Now it won’t create the most idiomatic Kotlin code, but it’s a start. And it’s the best place to really start learning Kotlin. Whenever you convert a file you’re able to go through with a full understanding of what the code does and start to learn how Kotlin handles different parts of your Java code.\n\nSo why would we want to even begin to use Kotlin instead of Java? Well, we get a lot of things free out of the box with Kotlin that can make our code a lot cleaner and easier to read. The first thing to recognize is that if you have a class that just has properties, like a class to represent a JSON object, Kotlin has what they call Data Classes. It generates getters/setters, hashCode, toString, and equals in the background and into bytecode. So a large class with a ton of boilerplate collapses to one line.\n\n```kotlin\ndata class User(val name: String, val age: Int)\n```\n\nI found that a lot of methods in classes can collapse to one line due to the null safety features in Kotlin.\n\nWe’ve all seen code like this in any Java code base\n\n```kotlin\nif (someObject != null && someObject.getSomeOtherObject() != null) {\n String someString = someObject.getSomeOtherObject().getSomeString();\n if (someString != null) {\n return someString;\n }\n return “”;\n}\n```\n\nJust so much unnecessary code which can get very confusing, especially when this is everywhere in your code base. In Kotlin it turns into this:\n\n```kotlin\nreturn someObject?.getSomeOtherObject()?.getSomeString() ?: \"\"\n```\n\nSo what we see here are a few things. To give some context you can set variables to either have a null option or not. So in this code sample we’re assuming that someObject can be null, and so can someOtherObject. The ? mark gives you a safe call, so if it is null it just returns null instead of blowing up with a NullPointerException. Now the ?: is called the elvis operator and if the expression on the left side is null, it returns whatever is on the right side. The two code snippets do exactly the same. So imagine going through a lot of the major classes you may have in your legacy Java apps and being able to cut the lines of code down by a huge amount? It would make things much easier to follow, read, and understand.\n\nThis is the major feature that I think is really useful and helpful as you basically eradicate Null Pointer Exceptions. The best part is that IntelliJ is smart enough to know if you are not making a safe call with something that is nullable, so you get compile time errors! Add this to the ability to write lambdas, streams and filters, OOP and functional paradigms... all in Java 6 bytecode! Most things I’ve seen show that it compiles in about the same time as Java, so you won’t see a major increase in compile or build times which is important with some of these big major applications.\n\nOverall as you can probably tell, I think Kotlin is a pretty cool new language that may allow a lot of people to transform some of their older code bases into more concise and easier to read code without much work at all and without the need for it to be all or nothing. Along with this, it’s not as huge of a paradigm shift as something like Scala, so it’s a lot easier to get a team who is new to Kotlin to start using it and understand it.\n\nI didn’t go through everything in the language, so definitely check out the docs and other links I’ll have below.\n\nUseful Links:\n\n* Kotlin Website: [https://kotlinlang.org/](https://kotlinlang.org/)\n* Kotlin Koans (Good interactive tutorial): [https://kotlinlang.org/docs/tutorials/koans.html](https://kotlinlang.org/docs/tutorials/koans.html)\n* Amazing talk by Jake Wharton on Kotlin (Android): [https://www.youtube.com/watch?v=A2LukgT2mKc](https://www.youtube.com/watch?v=A2LukgT2mKc)\n\nThank you! :)\n\n","author":"Kenneth Ford","date":"2016-10-27","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Andrey Breslav: Kotlin Coroutines, JVMLS 2016","url":"https://www.youtube.com/watch?v=4W3ruTWUhpw","body":"\n\n\n\n","author":"Andrey Breslav","date":"2016-08-03","type":"video","categories":["Kotlin","Coroutines"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Spring Tips: the Kotlin Programming Language","url":"https://www.youtube.com/watch?v=90WRtrbRi0Y","body":"\n\nHi Spring fans! In this tip, we’ll quickly look at the Kotlin programming language and some very high-level things you need to know when building Spring Boot and Kotlin applications\n\n\n\n","author":"Josh Long","date":"2016-10-19","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"PaperParcel with Kotlin","url":"http://www.tutorialforandroid.com/2016/08/paperparcel-with-kotlin.html","body":"\nWhen I started to code in kotlin, one of the libraries that I found that was really useful is [PaperParcel](https://github.com/grandstaish/paperparcel). PaperParcel is a library that would generate Parcelable using annotation. The good thing about it, is that it will reduce the amount of code and mistake you could make if you manually create those classes. Having said that, the library is not purely for Kotlin and it could be used in Java Android project. \n\nTo use it in kotlin \nYou will need to add these to your app build gradle dependencies \n\n```gradle\ncompile 'com.github.grandstaish.paperparcel:paperparcel:1.0.0-rc4'\ncompile 'com.github.grandstaish.paperparcel:paperparcel-kotlin:1.0.0-rc4'\nkapt 'com.github.grandstaish.paperparcel:compiler:1.0.0-rc4'\n```\n\nwhile still in that gradle file, add these before dependencies \n\n```gradle\nkapt {\n generateStubs = true\n}\nrepositories {\n maven { url 'https://jitpack.io' }\n}\n```\n\nNow the fun part, this is taken from my app [Daily Picture Quotes](https://play.google.com/store/apps/details?id=com.monmonja.dailyPictureQuotes) \n\n```kotlin\n@PaperParcel\ndata class QuoteImage(val id: String = \"\",\n val name: String = \"\",\n val text_quote: String = \"\",\n val url: String = \"\",\n val created: String = \"\",\n val cursor:String? = \"\") : PaperParcelable {\n companion object {\n @JvmField val CREATOR = PaperParcelable.Creator(QuoteImage::class.java)\n }\n}\n```\n\nThats about it, you can use QuoteImage to pass around Activities or Fragment or use it with your custom class. \n\nTwo things you have to remember is that your data class name must be supplied in PaperParcelable.Creator and every time you make changes to this data class (atleast for me) you have to do rebuild project. \n\nIf this interest you then have a check on the [kotlin usage](https://github.com/grandstaish/paperparcel/wiki/Kotlin-Usage) section of their github page. \n\nHope this helps :) \n","author":"Almond Joseph Mendoza","date":"2016-08-10","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Redux for Android using Kotlin","url":"https://www.youtube.com/watch?v=BUAxqiGrKOc","body":"\n\n","author":"Nevin Chen","date":"2016-11-22","type":"video","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"ZH","enclosure":null},{"title":"Kotlin 1.0 is finally released!","url":"https://programmingideaswithjake.wordpress.com/2016/02/22/kotlin-1-0-is-finally-released/","body":"\nLast week, there was a wonderful announcement: (see title of post)! No more milestones, betas, or release candidates required! Obviously, release candidates for later versions will be coming out, but now you don’t have to worry about them if you don’t want to.\n\nIf you’re like me and were waiting until release before trying to convince company management to consider Kotlin as a development option, now is the time to speak out!\n\nIn celebration of Kotlin’s proper release, I will be doing a short series of articles describing some of my favorite things about the language. Starting this weekend with a quick overview of smaller features that I don’t have a ton to say about. I’m calling it Kotlin Month, and I only slightly regret that the first one will be in one month while the others are in the next month :P\n\nAlso, you may notice that there’s now a page at the top pertaining to Kotlin articles. This won’t be much more useful than selecting the Kotlin tag from the tag cloud to the right, but it will at least stay there, even if Kotlin posts dwindle far enough to remove the tag from the cloud.\n","author":"Jacob Zimmerman","date":"2016-02-23","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Scala vs Kotlin: Pimp my library","url":"https://blog.frankel.ch/scala-vs-kotlin/1/","body":"\nI’ve been introduced to the world of immutable data structures with the Scala programming language - to write I’ve been introduced to the FP world would sound too presumptuous. Although I wouldn’t recommend its usage in my day-to-day projects, I’m still grateful to it for what I learned: my Java code is now definitely not the same because Scala made me aware of some failings in both the language **and** my coding practices.\n\nOn the other hand, I became recently much interested in [Kotlin](https://kotlinlang.org/), another language that tries to bridge between the Object-Oriented and Functional worlds. In this serie of articles, I’d like to compare some features of Scala and Kotlin and how each achieve it.\n\nIn this article, I’ll be tackling how both offer a way to improve the usage of _existing_ Java libraries.\n\n## Scala\n\nLet’s start with Scala, as it coined the term [Pimp My Library](http://www.artima.com/weblogs/viewpost.jsp?thread=179766) 10 years ago.\n\nScala’s approach is based on _conversion_. Consider a base type lacking the desired behavior. For example, Java’s `double` primitive type - mapped to Scala’s `scala.Double` type, is pretty limited.\n\nThe first step is to create a new type with said behavior. Therefore, Scala provides a `RichDouble` type to add some methods _e.g._ `isWhole()`.\n\nThe second step is to provide an _implicit_ function that converts from the base type to the improved type. The signature of such a function must follow the following rules:\n\n* Have a single parameter of the base type\n* Return the improved type\n* Be tagged `implicit`\n\nHere’s how the Scala library declares the `Double` to `RichDouble` conversion function:\n\n\n```scala\nprivate[scala] abstract class LowPriorityImplicits {\n ...\n implicit def doubleWrapper(x: Double) = new runtime.RichDouble(x)\n ...\n}\n```\n\nAn alternative is to create an _implicit class_, which among other requirements must have a constructor with a single parameter of base type.\n\nThe final step step is to bring the conversion _in scope_. For conversion functions, it means importing the function in the class file where the conversion will be used. Note that in this particular case, the conversion function is part of the automatic imports (there’s no need to explicitly declare it).\n\nAt this point, if a function is not defined for a type, the compiler will look for an imported conversion function that transforms this type to a new type that provides this function. In that case, the type will be replaced with the conversion function.\n\n```kotlin\nval x = 45d\nval isWhole = x.isWhole // Double has no isWhole() function\n\n// But there's a conversion function in scope which transforms Double to RichDouble\n// And RichDouble has a isWhole() function\nval isWhole = doubleWrapper(x).isWhole\n```\n\n## Kotlin\n\nOne of the main reasons I’m cautious about using Scala is indeed the implicit part: it makes it much harder to reason about the code - just like AOP. Homeopathic usage of AOP is a life saver, widespread usage is counter-productive.\n\nKotlin eschews implicitness: instead of conversions, it provides [extension methods](https://kotlinlang.org/docs/reference/extensions.html#extension-functions) (and properties).\n\nLet’s analyze how to add additional behavior to the `java.lang.Double` type.\n\nThe first step is to provide an extension function: it’s a normal function, but grafted to an existing type. To add the same `isWhole()` function as above, the syntax is the following:\n\n```kotlin\nfun Double.isWhole() = this == Math.floor(this) && !java.lang.Double.isInfinite(this)\n```\n\nAs for Scala, the second step is to bring this function in scope. As of Scala, it’s achieved through an import. If the previous function has been defined in any file of the `ch.frankel.blog` package:\n\n```kotlin\nimport ch.frankel.blog.isWhole\n\nval x = 45.0\nval isWhole = x.isWhole // Double has no isWhole() function\n\n// But there's an extension function in scope for isWhole()\nval isWhole = x == Math.floor(x) && !java.lang.Double.isInfinite(x)\n```\n\nNote that extension methods are resolved **statically**.\n\n> Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on instances of this class.\n> \n> We would like to emphasize that extension functions are dispatched statically, i.e. they are not virtual by receiver type. This means that the extension function being called is determined by the type of the expression on which the function is invoked, not by the type of the result of evaluating that expression at runtime.\n\n## Conclusion\n\nObviously, Scala has one more indirection level - the conversion. I let anyone decide whether this is a good or a bad thing. For me, it makes it harder to reason about the code.\n\nThe other gap is the packaging of the additional functions. While in Scala those are all attached to the enriched type and can be imported as a whole, they have to be imported one by one in Kotlin.\n\n","author":"Nicolas Fränkel","date":"2016-07-10","type":"article","categories":["Kotlin","Scala"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"JMock and Kotlin","url":"http://www.oneeyedmen.com/jmock-and-kotlin.html","body":"\n[JMock](http://www.jmock.org/) may have lost the mocking war, but for the London crowd it's still the go-to mocking tool.\nIt turns out that a little Kotlin fairy-dust can make it even more expressive.\n\nIn [my last post](/mocks-v-approvals-tests-part2.html) we saw a pretty vanilla use of JMock. In fact there was *one* nice\nKotlin'ism, defining an extension method on Mockery. So where in Java we would write\n\n```java\nmockery.checking(new Expectations() { {\n oneOf(progress).reset(2);\n oneOf(indexer).createIndex();\n} })\n```\n\nin Kotlin, by defining\n\n```kotlin\nfun Mockery.expecting(block: MyExpectations.() -> Unit) {\n this.checking(MyExpectations().apply(block))\n}\n```\n\nwe can write\n\n```kotlin\nmockery.expecting {\n oneOf(progress).reset(2)\n oneOf(indexer).createIndex()\n}\n```\n\nIn addition, in the name of more readable tests, I had added a subclass of Expectations\nto allow me to write, for example\n\n```kotlin\nmockery.expecting {\n givenActiveJournalIds(\n \"1\" to throwException(RuntimeException(\"oops\")),\n \"2\" to returnValue(journal2))\n }\n ...\n```\n\nThis was achieved with\n\n```kotlin\nclass MyExpectations : Expectations() {\n fun givenActiveJournalIds(vararg idResultPairs: Pair) {\n allowing(journals).loadActiveIds()\n will(returnValue(idResultPairs.map { it.first }))\n idResultPairs.forEach { pair ->\n allowing(journals).loadJournalWithArticles(pair.first, 99)\n will(pair.second)\n }\n }\n}\n```\n\nwhich is tighter in Kotlin, but nothing that you couldn't do in Java.\n\nLooking at a one of the tests, this plugs together into something like\n\n```kotlin\n@Test fun reports_exceptions_and_continues() {\n mockery.expecting {\n val x = RuntimeException(\"oops\")\n\n givenActiveJournalIds(\n \"1\" to throwException(x),\n \"2\" to returnValue(journal2))\n\n oneOf(progress).reset(2)\n oneOf(indexer).createIndex()\n\n never(indexer).index(JournalJson(journal1))\n oneOf(progress).exception(\"1\", x)\n\n oneOf(indexer).index(JournalJson(journal2))\n oneOf(progress).indexed(journal2)\n }\n refresher.refresh(journals, indexer, emptySet())\n}\n```\n\nThis isn't bad, but one of JMock's problems is that it doesn't differentiate between interactions\nthat are queries, and those that are operations. In this case the refresher queries the `journals`\nto find what needs to be indexed, then operates on the `indexer` to add them. Introducing\n`givenActiveJournalIds` gives a clue, but it would be nice to see the split more formally.\n\nWhat I'd like to see is\n\n```kotlin\n@Test fun reports_exceptions_and_continues() {\n val x = RuntimeException(\"oops\")\n mockery.given {\n activeJournalIds(\n \"1\" to throwException(x),\n \"2\" to returnValue(journal2))\n }.whenRunning {\n refresher.refresh(journals, indexer, emptySet())\n }.thenExpect {\n oneOf(progress).reset(2)\n oneOf(indexer).createIndex()\n\n never(indexer).index(JournalJson(journal1))\n oneOf(progress).exception(\"1\", x)\n\n oneOf(indexer).index(JournalJson(journal2))\n oneOf(progress).indexed(journal2)\n }\n}\n```\n\nThis can be achieved through 2 extension methods and a little class -\n\n```kotlin\nfun Mockery.expecting(expectations: Expektations.() -> Unit): Mockery {\n this.checking(Expektations().apply(expectations))\n return this\n}\n\nfun Mockery.whenRunning(block: () -> Unit) = ThenClause(this, block)\n\nclass ThenClause(private val mockery: Mockery, private val block: () -> Unit) {\n fun thenExpect(expectations: Expektations.() -> Unit) {\n mockery.expecting(expectations)\n block()\n mockery.assertIsSatisfied()\n }\n}\n```\n\nActually that trick [can be played in Java 8 too](https://github.com/dmcg/nowthen).\n\nIf you're really eagle-eyed, you may have noticed `Expektations` pop up in that example.\nThat's to support my final trick, an extension method on `Nothing`. Why?\n\nWell what if we wanted to simulate an exception in the indexing?\n\n```kotlin\n@Test fun `reports exceptions in indexing and continues`() {\n val x = RuntimeException(\"oops\")\n mockery.given {\n activeJournalIds(\n \"1\" to returnValue(journal1),\n \"2\" to returnValue(journal2))\n }.whenRunning {\n refresher.refresh(journals, indexer, emptySet())\n executor.runUntilIdle()\n }.thenExpect {\n oneOf(progress).reset(2)\n oneOf(indexer).createIndex()\n\n oneOf(indexer).index(JournalJson(journal1))\n will(throwException(x))\n oneOf(progress).exception(\"1\", x)\n\n oneOf(indexer).index(JournalJson(journal2))\n oneOf(progress).indexed(journal2)\n }\n}\n```\n\nThat `will()` as a separate statement has always bothered me about JMock - it should\nbind to the previous statement, but can't because `indexer.index(...)` returns `Unit`\n(`void` in Java). In Kotlin we can define\n\n```kotlin\nclass Expektations: Expectations() {\n fun Any?.will(action: Action) = super.will(action)\n // fun Nothing.will(action: Action) = super.will(action) Update 2016-05-17 - looks like this isn't needed, as Unit extends Any\n}\n```\n\nand now within our expectation blocks we can write\n\n``` koklin\n{\n oneOf(indexer).index(JournalJson(journal1)).will(throwException(x))\n // or\n allowing(journals).loadJournalWithArticles(\"1\", 99).will(returnValue(journal1))\n}\n```\n\nWith a bit of work I think that would allow a typed JMock `Action` so that you could only\n`returnValue` with the correct type, but I haven't pulled on that thread yet.\n\nThe final bonus marks in this post go for spotting\n\n```kotlin\n@Test fun `reports exceptions in indexing and continues`()\n```\n\nIgnoring the fact that it breaks [Prism](http://prismjs.com/)'s Kotlin highlighter, this hack was pointed out by\n[Nat Pryce](http://natpryce.com) - backticks allow spaces in method names, giving beautifully\nreadable specs in code and test runners.\n\n","author":"Duncan McGregor","date":"2016-05-01","type":"article","categories":["Unit Testing","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Android: Improving sign-in experience with Google Sign-In and SmartLock","url":"https://medium.com/@p.tournaris/android-improving-sign-in-experience-with-google-sign-in-and-smartlock-f0bfd789602a#.djgn5w44q","body":"","author":"Pavlos-Petros Tournaris","date":"2016-12-14","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Functions as Data","url":"http://cloudmark.github.io/Functions-As-Data/","body":"\n\n![Brain](http://cloudmark.github.io/images/func_as_data/brain.png)\n \n Programming languages have evolved largely through a series of abstractions; these abstractions mostly deal with control (e.g. functions) or data. In the post, [Houses, Arrays and Higher Order Functions](http://cloudmark.github.io/Higher-Order-Functions-On-Arrays/), we have focused on the use of functions as control elements and have delved into the concept of higher order functions. Today we will revisit functions and focus on their use as data elements. Using functions to represent data might seem pretty counter intuitive at first but this blurred line between functions as control elements and functions as data elements is a powerful concept. \n\n \n# Sets\nIn order to illustrate how functions can be used as data elements we will create a Set library with the following operations: `union`, `intersection` and `difference`. We will define a set using the characteristic function `T -> Boolean` i.e. a function which takes an element `T` as input and return a `true` or `false` depending on whether the element is contained within the set. Using classic OOP we can define a set as follows: \n\n\n```kotlin\nclass Set(vararg values: T) {\n var elements: List = values.toList()\n fun contains(element:T): Boolean = this.elements.contains(element)\n}\n```\n\nIn this case a set is defined as a class with a generic type `T`, we will use the underlying list data structure `elements` to implement the `contains` function. We can use the OOP representation as follows: \n\n\n```kotlin\nval s1 = Set(1)\nval s2 = Set(2, 3, 4)\n```\n\nUsing functions as data elements we would implement a Set as follows: \n\n```kotlin\nfun setOf(element: T): (T) -> Boolean = { test -> element!!.equals(test) }\nfun contains(set: (T)->Boolean, element: T): Boolean = set(element)\n```\n\nThe function `setOf` is a _constructor_ function (as defined by SICP) which takes in an `element` and returns a higher order functions that implements the characteristic function `(T) -> Boolean`. `contains` just delegates the test to the `setOf` higher order function by calling `set(element)`. Some observant readers might have noticed that the class `Set` can ingest a number of values whilst the `setOf` function can only ingest one value. Using the `union` operator (defined further on) we can extends the `setOf` function to accept a variable number of elements `T`. \n\n```kotlin \nfun setOf(vararg elements: T): (T) -> Boolean {\n return elements.map { setOf(it) } .reduce { s, t -> union(s, t) }\n}\n```\n\n\nUsing the `setOf` function we can define the set `s1` and `s2` as follows: \n\n```kotlin\nval s1 = setOf(1)\nval s2 = setOf(2, 3, 4)\n```\n\nNote that even though the representation is completely different the end user consuming either library will not be exposed to the underlying details of our implementations (OOP vs Functions). To an end user (except for minor syntactic differences) these two Sets are not different from each another. \n\n\n# Union\nNow that we have a means of representing a set, let us implement `union` in both representations. In the OOP approach we would implement union as follows: \n\n```kotlin\nclass Set(vararg values: T) {\n fun union(other:Set): Set {\n val unionSet = Set()\n val elements = ArrayList(this.elements)\n elements.addAll(other.elements.filter { x -> !this.elements.contains(x) })\n unionSet.elements = elements\n return unionSet\n }\n ...\n}\n```\n\nIn this case we are using the backing data stucture `elements` to keep track of what is _in_ the set. We can test this implementation as follows: \n\n\n```kotlin\nval s1 = Set(1)\nval s2 = Set(2, 3, 4)\nprintln(s1.union(s2).contains(1)) // -> true\nprintln(s1.union(s2).contains(2)) // -> true\nprintln(s1.union(s2).contains(3)) // -> true\nprintln(s1.union(s2).contains(4)) // -> true\nprintln(s1.union(s2).contains(5)) // -> false\nprintln(s1.union(s2).contains(0)) // -> false\n```\n\nUsing functions we get a much more pure definition (mathematically speaking): \n\n\n```kotlin\nfun union(s1: (T)->Boolean, s2: (T)->Boolean): (T)->Boolean = \n {element -> s1(element) || s2(element) }\n```\n\nAn `element` is contained in the union of set `s1` and `s2` if the `element` is either in set `s1` or `s2`. This is clearly represented by the line `element -> s1(element) || s2(element)`. Don't be fooled by the fact that Kotlin does not support structural types, had the language supported structural types our definition would be a bit more concise: \n\n```kotlin\nfun union(s1: Set, s2: Set):Set = \n {element -> s1(element) || s2(element) }\n```\n\nNeedless to say this is just semantic sugar; regular functions (with milk) will do just fine! One would use the union operator as follows: \n\n```kotlin\nval s1 = setOf(1)\nval s2 = setOf(2, 3, 4)\nprintln(contains(union(s1, s2), 1)) // -> true\nprintln(contains(union(s1, s2), 2)) // -> true\nprintln(contains(union(s1, s2), 3)) // -> true\nprintln(contains(union(s1, s2), 4)) // -> true\nprintln(contains(union(s1, s2), 5)) // -> false\nprintln(contains(union(s1, s2), 0)) // -> false\n```\n\nNote again that the usage is very similar and an end user would find it hard to believe that the Set is implemented using functions. \n\n# Intersection \nHaving defined `union`, `intersection` will only be one synaptic leap away. Let's start off with the OOP version. \n\n```kotlin\nclass Set(vararg values: T) {\n fun intersection(other:Set): Set {\n val intersectionSet= Set()\n val elements = ArrayList()\n elements.addAll(this.elements.filter { x -> other.contains(x) })\n intersectionSet.elements = elements\n return intersectionSet\n }\n ...\n}\n```\n\nOne would use the definition above as follows: \n\n```kotlin\nval s3 = Set(1, 2)\nval s4 = Set(2, 3, 4)\nprintln(s3.intersection(s4).contains(1)) // -> false\nprintln(s3.intersection(s4).contains(2)) // -> true\nprintln(s3.intersection(s4).contains(3)) // -> false\nprintln(s3.intersection(s4).contains(4)) // -> false\nprintln(s3.intersection(s4).contains(5)) // -> false\nprintln(s3.intersection(s4).contains(0)) // -> false\n```\n\nUsing functions, we would represent the intersection function as: \n\n```kotlin\nfun intersection(s1: (T)->Boolean, s2: (T)->Boolean): (T)->Boolean = \n { element-> s1(element) && s2(element) }\n```\n\nNote how close this function is to the original mathematical definition; an `element` is contained in the intersection of Set `s1` and `s2` if the `element` is contained in set `s1` and set `s2`, hence: \n\n```kotlin\nelement -> s1(element) && s2(element)\n```\n\nOne would use the above definition as follows: \n\n```kotlin\nval s3 = setOf(1, 2)\nval s4 = setOf(2, 3, 4)\nprintln(contains(intersection(s3, s4), 1)) // -> false\nprintln(contains(intersection(s3, s4), 2)) // -> true\nprintln(contains(intersection(s3, s4), 3)) // -> false\nprintln(contains(intersection(s3, s4), 4)) // -> false\nprintln(contains(intersection(s3, s4), 5)) // -> false\nprintln(contains(intersection(s3, s4), 0)) // -> false\n```\n\n\n# Difference \nFor completeness let us now implement `difference` in both representations. In the OOP approach we would implement difference as follows: \n\n```kotlin\nclass Set(vararg values: T) {\n fun difference(other:Set): Set {\n val differenceSet= Set()\n val elements = ArrayList()\n elements.addAll(this.elements.filter { x -> !other.contains(x) })\n differenceSet.elements = elements\n return differenceSet\n }\n ...\n}\n```\n\nUsing functions we can implement this using:\n\n```kotlin\nfun difference(s1: (T)->Boolean, s2: (T)->Boolean): (T)->Boolean = \n {element-> s1(element) && !s2(element) }\n```\n\n\n\n# Set of multiple elements \nBefore we conclude I would like to give an intuition for the function\n\n```kotlin\nfun setOf(vararg elements: T): (T) -> Boolean {\n return elements.map { setOf(it) } .reduce { s, t -> union(s, t) }\n}\n```\n\nSpecifically how we used `map` and `reduce` to create a _characteristic function_ which accepts multiple elements as follows: \n\n```kotlin \nval s3 = setOf(2, 3, 4, 7)\n```\n\nWhat `elements.map { setOf(it) }` does is map all `elements` to a characteristic function, hence 2 becomes: \n\n```kotlin\ntest -> 2.equals(test)\n```\n\n3 becomes: \n\n```kotlin\ntest -> 3.equals(test)\n```\n\nand so on. \n\nThe `reduce` function will combine the characteristic functions as follows: \n\n```kotlin\nunion (\n union(\n union(\n {test -> 2.equals(test)}, \n {test -> 3.equals(test)}\n ), \n {test -> 4.equals(test)}\n ), \n {test -> 7.equals(test)}\n)\n```\n\nEach `union` function creates a new characteristic function combining the underlying two characteristic functions. For e.g. \n\n```kotlin\nunion(\n {test -> 2.equals(test)}, \n {test -> 3.equals(test)}\n)\n```\n\n\nwould create the following characteristic function: \n\n```kotlin\n{test -> \n {test1 -> 2.equals(test1)}(test) || \n {test2 -> 3.equals(test2)}(test)\n}\n```\n\nIf we want to test whether 2 is in the set union, we would reduce the characteristic function as follows: \n\n```kotlin\nunion({test -> 2.equals(test)}, {test -> 3.equals(test)})(2)\n{test -> \n {test1 -> 2.equals(test1)}(test) || // 2 here is the element in the set s1 \n {test2 -> 3.equals(test2)}(test) // 3 here is the element in the set s2\n}(2) // 2 is the value to test. \n```\n\nReplace all occurrences of `test` with the value 2, we obtain: \n\n```\n{test1 -> 2.equals(test1)}(2) || {test2 -> 3.equals(test2)}(2)\n```\n\nReplace all occurrences of `test1` and `test2` with the value 2, we obtain: \n\n```\n2.equals(2) || 3.equals(2)\ntrue\n```\n\nHence the characteristic function for the set union between `s1` and `s2` when applied to 2 has reduced to true, which is correct. \n\n\n# Conclusion\nIn this post we have looked at how we can use functions as data elements. Using functions as a data representation might feel unnatural at first but this blurred boundary between functions as elements of control and functions as elements of data is quite powerful. I really hope that you find this technique useful. Stay safe and keep hacking!\n\n \n\n","author":"Mark Galea","date":"2016-10-19","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The Road to Gradle Script Kotlin 1.0","url":"https://blog.gradle.org/kotlin-scripting-update","body":"\nFive months ago we [announced the first pre-release of Gradle Script Kotlin](/kotlin-meets-gradle), and we thought now would be a good time to review the progress we’ve made since. We have shipped eight additional pre-releases during that time, and the road to 1.0 is looking clearer every day. So let’s take a look at the ground we’ve covered so far and where we’re going from here, shall we?\n\n## v0.1.0\n\nAs you may recall, this is what our [`hello-world` sample](https://github.com/gradle/gradle-script-kotlin/blob/cc14d3/samples/hello-world/build.gradle.kts) looked like at the time of our first release:\n\n```kotlin\nimport org.gradle.api.plugins.*\nimport org.gradle.script.lang.kotlin.*\n\napply()\n\nconfigure {\n mainClassName = \"samples.HelloWorld\"\n}\n\nrepositories {\n jcenter()\n}\n\ndependencies {\n \"testCompile\"(\"junit:junit:4.12\")\n}\n```\n\nOh, that annoying `org.gradle.script.lang.kotlin.*` import! The publicly condemned, IDE unfriendly, string-based `\"testCompile\"` dependency configuration! And of course—for those souls brave enough to have tried them—the infamous `generateKtsConfig` and `patchIdeaConfig` tasks required to get Kotlin-based build scripts working in IDEA. These were early days, no doubt, and they brought with them a few rough edges.\n\nBut despite its flaws, the programming language and IDE experience in 0.1.0 was already so good it got us hooked. As for the rough edges, we could already see ways to smooth them out, which led to the release of [0.2.0](https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.2.0) one month later.\n\n## v0.2.0\n\nWith [implicit imports](https://github.com/gradle/gradle-script-kotlin/issues/33) and a [tooling-friendly alternative to string-based dependency configurations](https://github.com/gradle/gradle-script-kotlin/issues/36), `hello-world` 0.2.0 started looking clean and concise:\n\n```kotlin\napply()\n\nconfigure {\n mainClassName = \"samples.HelloWorld\"\n}\n\nrepositories {\n jcenter()\n}\n\ndependencies {\n testCompile(\"junit:junit:4.12\")\n}\n```\n\n[Seamless project imports](https://github.com/gradle/gradle-script-kotlin/issues/26) meant that Kotlin-based builds in IDEA started working out of the box, and the days of mistyping `generateKtsConfig` and `patchIdeaConfig` were no more.\n\nPerhaps most importantly, 0.2.0’s [support for build script dependencies and external plugins](https://github.com/gradle/gradle-script-kotlin/issues/29) made Gradle Script Kotlin a viable choice for many real-world projects.\n\n## v0.3.0\n\n[0.3.0](https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.3.0) was a major milestone for the project, as it was the first version to be included in a production Gradle distribution—[Gradle 3.0](https://github.com/gradle/gradle/releases/tag/v3.0.0), no less!\n\nAnd 0.3.0 was all about that [Kotlin](https://kotlin.link/)! The [new Kotlin 1.1-M01 compiler](https://blog.jetbrains.com/kotlin/2016/07/first-glimpse-of-kotlin-1-1-coroutines-type-aliases-and-more/), support for [Kotlin-based plugins](https://github.com/gradle/gradle-script-kotlin/issues/84) and [`buildSrc` directories](https://github.com/gradle/gradle-script-kotlin/issues/86) plus some sugary [Kotlin-Groovy interoperability](https://github.com/gradle/gradle-script-kotlin/issues/103) primitives:\n\n```kotlinnp\ngradle.buildFinished(closureOf {\n println(\"$action finished\") // $action refers to BuildResult.getAction()\n})\n```\n\nWith Gradle 3.0 out the door, the #gradle channel of the public [Kotlin Slack](http://kotlinslackin.herokuapp.com/) saw an increase in participation which helped us greatly in prioritizing the work that would come next.\n\n## v0.3.1\n\nWe noticed people struggling with the lack of a more type-safe and IDE-friendly way of configuring dependencies, so [0.3.1](https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.3.1) came with a [much-improved dependencies DSL](https://github.com/gradle/gradle-script-kotlin/issues/107):\n\n```kotlin\ndependencies {\n\n default(group = \"org.gradle\", name = \"foo\", version = \"1.0\") {\n isForce = true\n }\n\n compile(group = \"org.gradle\", name = \"bar\") {\n exclude(module = \"foo\")\n }\n\n runtime(\"org.gradle:baz:1.0-SNAPSHOT\") {\n isChanging = true\n isTransitive = false\n }\n\n testCompile(group = \"junit\", name = \"junit\")\n\n testRuntime(project(path = \":core\")) {\n exclude(group = \"org.gradle\")\n }\n}\n```\n\nThe [upgrade to Kotlin 1.1-dev-2053](https://github.com/gradle/gradle-script-kotlin/issues/108) notably enhanced the performance of code assistance within IDEA and thanks to a [valuable member of the community](https://github.com/tyvsmith) the first Gradle Script Kotlin [Android sample](https://github.com/gradle/gradle-script-kotlin/tree/96b6fe/samples/hello-android) was published.\n\n## v0.3.2\n\nWith [0.3.2](https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.3.2) we decided to tackle [the dreaded `it` problem](https://www.youtube.com/watch?v=vv4zh_oPBTw&feature=youtu.be&t=1387) head-on via [runtime code generation of Kotlin extensions](https://github.com/gradle/gradle-script-kotlin/issues/117). What is the dreaded `it` problem? Take the use of [`copySpec`](https://docs.gradle.org/3.1/javadoc/org/gradle/api/Project.html#copySpec(org.gradle.api.Action)) as an example. Prior to 0.3.2, one would have written:\n\n```kotlin\ncopySpec {\n it.from(\"src/data\")\n it.include(\"*.properties\")\n}\n```\n\nThis syntax didn’t read very well, and was a departure from the fluid, readable DSL Gradle has long been known for. But never fear—with 0.3.2 `it` was gone:\n\n```kotlin\ncopySpec {\n from(\"src/data\")\n include(\"*.properties\")\n}\n```\n\n## v0.3.3 and v0.4.0\n\nThe recently-released versions [0.3.3](https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.3.3) and [0.4.0](https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.4.0) shipped the [first](https://github.com/gradle/gradle-script-kotlin/issues/137) of a series of improvements to [multi-project builds](https://github.com/gradle/gradle-script-kotlin/issues/112) including the ability to [define custom build logic using Kotlin in `buildSrc`](https://github.com/gradle/gradle-script-kotlin/blob/7c74044cd84c4c426f1bca9af9f48bf332620c73/samples/multi-project-with-buildSrc/README.md).\n\n[0.4.0](https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.4.0) is available now and will ship with the forthcoming Gradle 3.2 distribution.\n\n## Toward v1.0.0\n\nWhat’s next, you ask? Here are some of the highlights of our upcoming releases in three key areas:\n\n1. [Performance](https://github.com/gradle/gradle-script-kotlin/issues/160): Faster project configuration via caching of compiled build scripts ([#31](https://github.com/gradle/gradle-script-kotlin/issues/31)).\n2. [Usability](https://github.com/gradle/gradle-script-kotlin/issues/54): Type-safe accessors for extensions and conventions contributed by plugins ([#159](https://github.com/gradle/gradle-script-kotlin/issues/159)); Comprehensive documentation ([#106](https://github.com/gradle/gradle-script-kotlin/issues/106)).\n3. [Convenience](https://github.com/gradle/gradle-script-kotlin/issues/30): Declarative and tooling-friendly application of plugins, a.k.a., the `plugins` block ([#168](https://github.com/gradle/gradle-script-kotlin/issues/168)).\n\nAltogether, here’s how we envision the `hello-world` sample will look in Gradle Script Kotlin 1.0:\n\n```kotlin\nplugins {\n application\n}\n\napplication {\n mainClassName = \"samples.HelloWorld\"\n}\n\nrepositories {\n jcenter()\n}\n\ndependencies {\n testCompile(\"junit:junit:4.12\")\n}\n```\n\nHow does that look to you? We’d love to hear what you think.\n\nA big thanks to everyone that’s been along for the ride so far, and if you’re just getting started with Gradle Script Kotlin, welcome!\n\n","author":"Rodrigo B. de Oliveira","date":"2016-10-26","type":"article","categories":["Kotlin","Gradle"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Playing with Spring Boot, Vaadin and Kotlin","url":"https://blog.frankel.ch/playing-with-spring-boot-vaadin-and-kotlin","body":"\nIt’s no mystery that I’m a fan of both Spring Boot and Vaadin. When the [Spring Boot Vaadin add-on](https://github.com/vaadin/spring) became GA, I was ecstatic. Lately, I became interested in [Kotlin](https://kotlinlang.org/), a JVM-based language offered by JetBrains. Thus, I wanted to check how I could develop a small Spring Boot Vaadin demo app in Kotlin – and learn something in the process. Here are my discoveries, in no particular order.\n\n### Spring needs non-final stuff\n\nIt seems Spring needs `@Configuration` classes and `@Bean` methods to be non-final. As my previous Spring projects were in Java, I never became aware of that because I never use the `final` keyword. However, Kotlin classes and methods are final _by default_: hence, you have to use the open keyword in Kotlin.\n\n```kotlin\n@Configuration\nopen class AppConfiguration {\n @Bean\n @UIScope\n open fun mainScreen() = MainScreen()\n}\n```\n\n### No main class\n\nSpring Boot applications require a class with a `public static void main(String... args)` method to reference a class annotated with `@SpringBootApplication`. In general, those two classes are the same.\n\nKotlin has no concept of such static methods, but offers pure functions and objects. I tried to be creative by having an annotated object referenced by a pure function, both in the same file.\n\n```kotlin\n@SpringBootApplication\nopen class BootVaadinKotlinDemoApplication\n\nfun main(vararg args: String) {\n SpringApplication.run(arrayOf(BootVaadinKotlinDemoApplication::class.java), args)\n}\n```\n\n### Different entry-point reference\n\nSince the main function is not attached to a class, there’s no main class to reference to launch inside the IDE. Yet, Kotlin creates a .class with the same name as the file name suffixed with `Kt`.\n\nMy file is named `BootVaadinKotlinDemoApplication.kt`, hence the generated class name is `BootVaadinKotlinDemoApplicationKt.class`. This is the class to reference to launch the application in the IDE. Note that there’s no need to bother about that when using `mvn spring-boot:run` on the command-line, as Spring Boot seems to scan for the main method.\n\n### Short and readable bean definition\n\nJava syntax is seen as verbose. I don’t think it’s a big issue when its redundancy is very low compared to the amount of useful code. However, in some cases, even I have to admit it’s a lot of ceremony for not much. When of such case is defining beans with the Java syntax:\n\n```kotlin\n@Bean @UIScope\npublic MainScreen mainScreen() {\n return new MainScreen();\n}\n```\n\nKotlin cuts through all of the ceremony to keep only the meat:\n\n* No semicolon required\n* No new keyword\n* Block replaced with an equal sign since the body consists of a single expression\n* No return keyword required as there’s no block\n* No return type required as it can easily be inferred\n\n```kotlin\n@Bean @UIScope\nfun mainScreen() = MainScreen()\n```\n\nSpring configuration files are generally quite long and hard to read. Kotlin makes them much shorter, without sacrificing readability.\n\n### The init block is your friend\n\nIn Java, the constructor is used for different operations:\n\n1. storing arguments into attributes\n2. passing arguments to the super constructor\n3. other initialization code\n\nThe first operation is a no-brainer because attributes are part of the class signature in Kotlin. Likewise, calling the super constructor is handled by the class signature. The rest of the initialization code is not part of the class signature and should be part of an `init` block. Most applications do not this part, but Vaadin needs to setup layout and related stuff.\n\n```kotlin\nclass MainScreenPresenter(tablePresenter: TablePresenter,\n buttonPresenter: NotificationButtonPresenter,\n view: MainScreen, eventBus: EventBus) : Presenter(view, eventBus) {\n\n init {\n view.setComponents(tablePresenter.view, buttonPresenter.view)\n }\n}\n```\n\n### Use the apply method\n\nKotlin has a standard library offering small dedicated functions. One of them is apply, defined as `inline fun T.apply(f: T.() -> Unit): T (source)`. It’s an extension function, meaning every type will have it as soon as it’s imported into scope. This function requires an argument that is a function and that returns nothing. Inside this function, the object that has been apply-ed is accessible as `this` (and `this` is implicit, as in standard Java code). It allows code like this:\n\n```kotlin\nVerticalLayout(button, table).apply {\n setSpacing(true)\n setMargin(true)\n setSizeFull()\n}\n```\n\n### Factor view and presenter into same file\n\nKotlin makes code extremely small, thus some files might be only a line long (not counting import). Opening different files to check related classes is useless. Packages are a way to organize your code; I think files might be another way in Kotlin. For example, Vaadin views and presenters can be put into the same file.\n\n```kotlin\nclass NotificationButton: Button(\"Click me\")\n\nclass NotificationButtonPresenter(view: NotificationButton, eventBus: EventBus): Presenter(view, eventBus) { ... }\n\n```\n\n### Lambdas make great listeners\n\nAs of Java 8, single-method interfaces implemented as anonymous inner classes can be replaced with lambdas. Kotlin offers the same feature plus:\n\n* it allows to omit parentheses if the lambda is the only argument\n* if the lambda has a single argument, its default name is `it` and it doesn’t need to be declared\n\nBoth make for a very readable syntax when used in conjunction with the Vaadin API:\n\n```kotlin\nview.addValueChangeListener {\n val rowId = it.property.value\n val rowItem = view.containerDataSource.getItem(rowId)\n eventBus.publish(SESSION, rowItem)\n}\n```\n\nNote: still, more complex logic should be put into its [own function](https://morevaadin.com/content/lambdas-java-8/).\n\n","author":"Nicolas Frankel","date":"2016-01-10","type":"article","categories":["Kotlin","Spring","Vaadin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The Design and Construction of Modern Build Tools","url":"http://www.javamagazine.mozaicreader.com/JanFeb2017","body":"\nA look inside a modern JVM build tool—its architecture and implementation\n\nThe JVM has seen many build tools in the past 20 years. For Java alone, there’s been Ant, Maven, Gradle, Gant, and others, while in JVM languages, sbt is used for Scala, and Leiningen for Clojure. These tools are run by developers and by back-end systems multiple times a day, yet very little is formally documented about how they are implemented, what functionalities they do and should offer, and why.\n\nIn this article, I give an overview of what it takes to create a modern build tool, the kinds of functionality you should expect, and how that functionality is implemented in modern tools. These observations are derived from my experience building software for decades and also from an experimental build tool I am working on called [Kobalt](http://bit.ly/kobaltbuild), which performs builds for the JVM language Kotlin, [previously described](http://bit.ly/2hKDEji) in this magazine.\n\n## Motivation\n\nKobalt was born from my observation that while the Gradle tool was a clear step forward in versatility and expressive build file syntax, it also suffered from several shortcomings, some of them related to its reliance on Groovy. I therefore decided to create a build tool inspired by Gradle but based on Kotlin, JetBrains’ language.\n\nKobalt is not only written in Kotlin, its build files are also valid Kotlin programs with a thin DSL that will look familiar to seasoned Gradle users. (Note that the latest version of Gradle also adopted Kotlin for its build file syntax, and the Groovy build file is going to be phased out, thus validating the approach taken with Kobalt.)\n\nIn this article, I discuss general concepts of build files and demonstrate Kobalt’s take on that feature. For readers unfamiliar with Kotlin, you should be able to follow along because the syntax is similar enough to Java’s.\n\n## Morphology of a Build Tool\n\nThe vast variety of build tools available on the JVM and elsewhere share a common architecture and similar basic functionalities:\n* The user needs to create one (or more) build files describing the steps required to create an application. The syntax to describe these build files is extremely varied: from simple property files to valid programming language source files and everything in between.\n* The build tool parses this build file and turns it into a graph of tasks that need to be executed in a specific order.\n* The tool then executes these tasks in the required order. The tasks can either be coded inside the build tool or require the invocation of external processes. The build tool should allow for tasks to do pretty much anything.\n\nOne of the oldest build tools on the JVM is Ant, which broke from the previous standard, make, that was in use up until that point. Ant introduced XML as the language for build files, which was quite innovative at the time. Ant also came up with the concept of tasks that can be defined either in the XML file or as external tasks implemented in Java that the tool looks up. Even though Ant is still used in legacy software, it is largely considered deprecated today and looked at as the “assembly language” of build tools: very flexible, offering a decent plugin architecture, but a tool that requires a lot of boilerplate for even the simplest build projects.\n\nNow, let’s dive more specifically into what you should expect from your build tool.\n\n## Syntax\n\nLet’s start with the most visible aspect of a build tool: the syntax of its build file.\n\nObviously, I want my build tool to have a clean and intuitive syntax, but you’ll be hard-pressed to find a general consensus on what a “clean syntax” is, so I won’t even try to define it. I would also argue that sometimes syntax is not as important as the ease with which you can write and edit your build file. For example, Maven’s pom.xml file has a verbose syntax, but I’ve found that editing it is pretty easy when I use an editor that’s aware of this file’s schema.\n\nGradle’s popularity came in good part from the fact that the syntax of its build file was Groovy, which is much more concise than XML. My personal experience has been that Gradle’s build files are easy to read but hard to write, and I’ll come back to this point below, but overall, there is a general agreement that the Gradle syntax is a step in the right direction.\n\nWhat is more controversial is the question of whether a build file should be using a purely declarative syntax (for example, XML or JSON) or be a valid program in some programming language.\n\nMy experience has led me to conclude that I want the syntax to look declarative (because it’s sufficient for most of my build files) but that I also want the power of a full programming language should I need it. And I don’t want to be obliged to escape to some other language when I have such a requirement: the build file needs to use the same syntax. This observation came from my realization that I have often wanted to have access to the full power of object-oriented programming in my build files, so that I can create base-class tasks that I can specialize with a few variations here and there. For example, if my project creates several libraries, I want to compile all these libraries with the same flags, but the libraries need to have a different name and version. This kind of problem is trivially solved in object-oriented languages with inheritance and method overriding, so having this kind of flexibility in a build file is desirable.\n\nOn a more general level, complex projects are often made of modules that share a varying degree of common settings and behaviors. The more your build system avoids requiring you to repeat these settings in multiple locations or different files, the easier it will be to maintain and evolve your build.\n\nAll build tools offer, in varying degrees, to help you set up your modules, their dependencies, and their shared parameters. But I can’t say I have found one that makes this “inherit and specialize” aspect very intuitive—not even my own build tool. Maybe the solution is for modules to be represented by actual classes in the programming language of your build files so you can use the familiar “inherit and override” pattern to capture this reuse.\n\nIn the meantime, I think the approach of using a DSL that is a valid program and that offers you all the facilities of a programming language should you ever need them (`if`, `else`, `classes`, `inheritance`, `composition`, and so on) is a clear step in the right direction.\n\n## Dependencies\n\n\nThe #1 job of a build tool is to execute a sequence of tasks in a certain order and to take various actions if any of these tasks fail. It should come as no surprise that all the build tools I have come across (on the JVM or outside) allow you to define tasks and dependencies between these tasks. However, a lot of tools don’t adequately address project dependencies: how do you specify that project C can be built only once projects A and B have been built?\n\nWith Gradle, you need to manipulate multiple build.gradle files that, in turn, refer to multiple settings.gradle files. In this design, dependent modules need to be defined across multiple files with different roles (build.gradle and settings.gradle), which can make keeping track of these dependencies challenging.\n\nWhen I started working on Kobalt, I decided to take a more intuitive approach by making it possible to define multiple projects in one build file, thereby making the dependency tree much more obvious. Here is what this looks like:\n\n```kotlin\nval lib1 = project {\n name = \"lib1\"\n version = \"0.1\"\n}\n\nval lib2 = project {\n name = \"lib2\"\n version = \"0.1\"\n}\n\nval mainProject = project(lib1, lib2) {\n name = \"mainProject\"\n version = \"0.1\"\n}\n```\n\nThe project directive (which is an actual Kotlin function) can take dependent projects as parameters, and Kobalt will build its dependency tree based on that information. All the projects are then sorted topologically, which means the build order can be either “lib1, lib2, mainProject” or “lib2, lib1, mainProject”—both of which are valid.\n\nAlso, note that the previous example is a valid and complete build file (and the repetition can be abbreviated further, but I’m keeping things simple for now).\n\nBeing able to keep the project dependencies in one centralized place makes it much easier to understand and modify a build, even for a complex project. Using multiple build files in the subprojects’ own directories should still be an option, though.\n\n## Make Simple Builds Easy and Complex Builds Possible\n\nA direct consequence of the functionality described in the previous section is that the build tool should let you create build files that are as bare bones as possible.\n\n**Convention over configuration**. Most projects usually contain just one module and are pretty simple in nature, so the build tool should make such build files short, and it should implement as many sensible defaults as possible. Some of these defaults include those shown in Table 1.\n\n| NAME | NAME OF THE CURRENT DIRECTORY |\n|---------------------------|------------------------------------------|\n| VERSION | “0.1” |\n| LANGUAGE(S) | AUTOMATICALLY DETECTED |\n| SOURCE DIRECTORIES | src/main/java, src, src/main/{language} |\n| MAIN RESOURCES | src/main/resources |\n| TEST DIRECTORIES | src/test/java, test, src/test/{language} |\n| TEST RESOURCES | src/test/resources |\n| MAVEN REPOSITORIES | MAVEN CENTRAL, JCENTER |\n| BINARY OUTPUT DIRECTORY | {SOMEROOT}/classes |\n| ARTIFACT OUTPUT DIRECTORY | {SOMEROOT}/libs |\n\n**Table 1.** *Sensible defaults for a Java-aware build tool*\n\nWith such defaults, the simplest build file for a project should literally be less than five lines long. And of course, the build tool could perform further analysis to do some additional guessing, such as inferring certain dependencies based\non the imports.\n\nComplex builds. Once you get past simple projects, the ability to easily modify a build is critical. Such modifications can be made statically (with simple changes to the build files) or dynamically (passing certain switches or values to the build run in order to alter certain settings). The latter operation is usually performed with profiles—values that trigger different actions in your build without having to modify your build file.\n\nMaven has native support for profiles, but Gradle relies on the extraction of environment values in Groovy to achieve a similar result, which reduces its flexibility. Profiles in Kobalt combine these two approaches with conditionals. You define profiles as regular Kotlin values, as shown here:\n\n```kotlin\nval experimental = false\nval premium = false\n```\n\nYou can use them in regular conditional statements anywhere in your build file, as shown in the following examples:\n\n\n```kotlin\nval p = project {\n name = if (experimental) \"project-exp\"\n else \"project\"\n version = \"1.3\"\n ...\n```\n\nProfiles can then be activated on the command line:\n\n```\n./kobaltw -profiles \\\n experimental,premium assemble\n```\n\nThis is an area where having your build file written in a programming language really brings benefits, because you can insert profile-triggered operations anywhere that is legal in that programming language:\n\n```kotlin\ndependencies {\n if (experimental)\n \"com.squareup.okhttp:okhttp:2.5.0\"\n else\n \"com.squareup.okhttp:okhttp:2.4.0\"\n}\n```\n\nHere, `if (experimental)` refers to the profile specified on the command line.\n\n## Performance\n\nYou want your build tool to be as fast as possible, which means that the overhead it imposes should be minimal and most of the time building should be expended by the external tools invoked by the build. On top of this obvious requirement, the build tool should also support two important features needed for speed: incremental tasks and parallel builds.\n\n**Incremental tasks**. For the purposes of build tools, a task is incremental if it can detect all by itself whether it needs to run. This is usually determined by calculating whether the output of the current run would be the same as that of the previous run and returning right away if such is the case. Most build tools support incremental tasks to varying degrees, and you can test how well your build tool performs on that scale by running the same command twice in a row and see how much work the build tool performs during the second run.\n\n**Parallel builds.** In contrast to incremental tasks, few build tools support parallel builds. I suspect the reason has a lot more to do with hardware than software; the algorithms to run tasks in parallel in the correct order are well known (if you are curious, look up “topological sorting”), but until recently, running build tasks in parallel wasn’t really worth it and didn’t always result in faster builds because of a simple technological hurdle: mechanical hard drives.\n\nBuild tasks are typically very I/O intensive. They read and write a lot of data to the disk, and with mechanical hard drives, this results in a lot of “thrashing” (the head of the hard drive being moved to different locations of the hard drive in rapid succession). Because build tasks keep being swapped in and out by the scheduler, the hard drive must move its head a lot, which results in slow I/O.\n\nThe situation has changed these past few years with the emergence of solid-state drives, which are much faster at handling this kind of I/O. As a consequence, modern build tools should not only support parallel builds but actually make them the default.\n\nFor example, Figure 1 is a diagram showing the multiple modules and their dependencies in the ktor project, a Kotlin web server.\n\nFrom this diagram, you can see that the core module needs to be built first. Once this is done, several modules can then be built in parallel, such as locations and features (as they both depend on core , but not on each other). As more modules are built, additional modules are scheduled to be built based on the dependency graph in Figure 1.\n\n![Figure 1.](http://i.imgur.com/Dfm29uL.png)\n\n**Figure 1.** *The dependencies in the ktor project*\n\nThe gain in build time with parallel build can be significant. For example, a recent build that was timed at 68 seconds in parallel required 260 seconds in a sequential build—effectively, a 4x differential.\n\n\n## Plugin Architecture\n\n> These days, nobody has time to go to a website, download a package, and manually install it. Build tools should be no exception, and they should self-update.\n\nNo matter how extensive the build tool is, it will never be able to address all the potential scenarios that developers encounter every day, so it also needs to be expandable. This is traditionally achieved by exposing a plug­in architecture that developers can use to extend the tool and have it perform tasks it wasn’t originally designed for. A build tool’s usefulness is directly correlated to the health and size of its plugin ecosystem.\n\nInterestingly, while OSGi is a respectable and well-specified architecture for plugin APIs, I don’t know of any build tool that uses it. Instead, build tools tend to invent their own plugin architecture, which is unfortunate.\n\nThis topic would require an entire book chapter of its own, so I’ll just mention that there are basically two approaches to plugin architecture. The first one is to give plugins full access to the internal structure of your tool, which is the approach adopted by Gradle (driven and facilitated by Gradle’s Groovy foundation).\n\nIn contrast, the Eclipse and IntelliJ IDEA development environments and Kobalt expose documented endpoints that plugins can connect to and use in order to observe and modify values in an environment that the build tool completely controls. I prefer this approach because it’s statically verifiable and much easier to document and maintain.\n\n## Package Management\n\nOn top of being a very versatile and innovative build system, Maven introduced what will most likely be a legacy that will far outlast it: the repository. I’m pretty sure that even if Maven becomes outdated and no longer used, we’ll still be referencing and downloading packages from the various Maven repositories that are available today.\n\nGiven the popularity of these repositories, a modern build tool should do the following:\n\n* Transparently support the automatic downloading of dependencies from these repositories (Maven, Gradle, and Kobalt all do this; Ant requires an additional tool).\n* Make it as easy as possible to make my projects available on these repositories. Maven and Gradle require plugins and quite a bit of boilerplate in your build file; Kobalt natively supports such uploads.\n\n## Auto-Completion in Your IDE\n\nDevelopers spend several hours every day in their IDE, so it stands to reason that they would expect all the facilities offered by their IDE to be available when they edit a build file. Build tools have been moderately successful at this, frequently offering partial syntactical support.\n\nInterestingly, Maven with its POM file has always been very well supported in IDEs because of its reliance on an XML format that’s fully described in an XML schema. The file is verbose, but auto-completion is readily available and reliable, and Maven’s schema is a very good example of how to define a proper XML file with very strict rules (for example, no attributes are ever used, so there’s never any hesitation about how to enter the data).\n\nThe more modern Gradle has been less successful in that area because of its reliance on Groovy and the fact that this language is dynamically typed. Kobalt’s reliance on Kotlin for its build file enables auto-completion to work in IntelliJ IDEA, without requiring any special efforts. Obviously, the upcoming Kotlin-based Gradle will enable similar levels of autocompletion as well.\n\n## Self-Updating\n\nThese days, nobody has time to go to a website, download a package, and manually install it. Build tools should be no exception, and they should self-update (or, at least, make it easy for you to update the tool). If the tool is available on a standard package manager on your system (brew, dpkg, and so on), great. But it should also be able to update itself so that such updates can be uniform across multiple operating systems. However, the tool itself is not the only part of your build that you want to keep updated. Dependencies are very important as well, and your build tool should help you stay current with these by informing you when new releases of dependencies are available.\n\n## Conclusion\n\nSoftware built in 2016 is much more complex than it was 20 years ago, and it’s important to hold our tools to a high standard. Libraries, IDEs, and design patterns are only a few components that need to adapt and improve as our software needs increase. Build tools are no exception, and we should be as demanding of them as we are of every other type of tool we use.\n\nCédric Beust ([@cbeust](https://twitter.com/cbeust)) has been writing Java code since 1996, and he has taken an active role in the development of the language and its libraries through the years. He holds a PhD in computer science from the University of Nice, France. Beust was a member of the expert group that designed annotations for the JVM.\n\n","author":"Cédric Beust","date":"2017-02-03","type":"article","categories":["Kotlin","Kobalt"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin + Android","url":"https://speakerdeck.com/dmytrodanylyk/kotlin-plus-android","body":"\n[Slides](https://speakerdeck.com/dmytrodanylyk/kotlin-plus-android)\n","author":"Dmytro Danylyk","date":"2016-04-21","type":"slides","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Setting up Kotlin with Android and tests","url":"http://engineering.pivotal.io/post/setting-up-kotlin-with-android-and-tests/","body":"\n\nI recently heard about [Kotlin](https://kotlinlang.org/) with the release of their 1.0 Beta last week. Kotlin is a modern programming language that runs in the JVM and is interoperable with Java. Kotlin can also be used to create Android apps.\n\nI was curious, so I decided to set up a small Android app using Kotlin and try out some different methods of testing.\n\n## Setting up the app\nSetting up a hello word Android app in Kotlin was actually quite easy! The Kotlin plugin for IntelliJ / Android Studo has a tool for converting your Java code to Kotlin, so you can get started really quickly! I was able to follow this [tutorial](https://kotlinlang.org/docs/tutorials/kotlin-android.html) to get my Android app set up.\n\nTwo points to watch out for:\n\n 1. Make sure you have installed the Kotlin plugins in Android Studio before you start\n\n 1. I had to highlight the text of my java file before selecting \"Convert Java File to Kotlin File\" in order to get the converter to work.\n\n## Android instrumentation tests\nI started by writing a simple Android Instrumentation test in Java (you can freely mix Java files and Kotlin files in your project and it seems to work fine). Once that was working, I converted it to Kotlin:\n\n```kotlin\nclass MainActivityTest : ActivityInstrumentationTestCase2(MainActivity::class.java) {\n private var mainActivity: Activity? = null\n\n @Throws(Exception::class)\n override fun setUp() {\n super.setUp()\n mainActivity = activity\n }\n\n fun test_itDisplaysHelloWorld() {\n val textView = mainActivity!!.findViewById(R.id.main_text) as TextView\n val actual = textView.text.toString()\n Assert.assertEquals(\"Hello World!\", actual)\n }\n}\n```\n\nThe only trouble I had was that after I converted the file, the Android Studio test runner configuration was broken. To fix it I had to edit my run configuration in Android Studio by navigating to `Run -> Edit Configurations -> Android Tests` and setting the instrumentation runner to `android.test.InstrumentationTestRunner`. After that, lo and behold, the test worked fine in Kotlin!\n\n## Robolectric tests\nAfter my resounding success at getting the Android Instrumentation Tests to work, I decided to try my luck at Robolectric. It turns out, Robolectric pretty much Just Worked too. Here's a Robolectric test written in Kotlin, equivalent to the instrumentation test above:\n\n```kotlin\n@RunWith(RobolectricGradleTestRunner::class)\n@Config(constants = BuildConfig::class)\nclass ExampleRobolectricTest {\n\n @Test\n fun itShouldDisplayHelloWorld() {\n val activity = Robolectric.setupActivity(MainActivity::class.java)\n val textView = activity.findViewById(R.id.main_text) as TextView\n\n assertThat(textView.text).isEqualTo(\"Hello World!\")\n }\n}\n```\n\n## Unit tests with Spek\n[Spek](https://jetbrains.github.io/spek/) is a testing framwork written in Kotlin with a pretty, rspec-like syntax. I would love to be able to write my Android tests using something like Spek, so I decided to try!\n### Bad news #1: Android Instrumentation tests + Spek\nSpek requires your tests to inherit from a base class called `Spek`. Android instrumentation tests require your tests to inherit from `InstrumentationTestCase`. As far as I can tell, this is a deal-breaker for using the two systems together, for the moment.\n\n### Bad news #2: Robolectric tests + Spek\nRobolectric doesn't specifically require your tests to inherit from any particular class, which theoretically opens the door to using it together with Spek. However, naively combining them doesn't work as expected, as the test runner cannot find any tests. I think the reason for this is that Robolectric relies on using the RobolectricTestRunner, which extends the `BlockJUnit4ClassRunner` (which identifies tests based on annotations), while Spek runs with it's own `JUnitClassRunner`.\n\nIn the future I may look into writing a RobolectricSpek test runner, but for now, it looks like these two systems do not play nicely together.\n\n### Finally, the good news\nAlthough Spek does not seem to be compatible with either Robolectric or Android instrumentation tests, it actually works fine as a replacement for vanilla JUnit tests. I think this kind of test is of dubious utility in a typical Android project, since there's usually not a lot of code that can be tested purely with JUnit, but if you have these kinds of tests, you could easily convert them to use Spek. Here's a sample test I wrote in my hello world app:\n\n```kotlin\nimport org.jetbrains.spek.api.Spek\nimport kotlin.test.assertEquals\n\nclass ExampleUnitTest : Spek() {\n init {\n given(\"Two numbers\") {\n val firstNumber = 3\n val secondNumber = 5\n on(\"adding the numbers\") {\n val result = firstNumber + secondNumber\n it(\"should return the correct sum\") {\n assertEquals(8, result)\n }\n }\n }\n }\n}\n```\n\n## Conclusion\nKotlin seems like a promising new language with a lot of features that make it nicer to use than Java. Setting up a \"Hello World\" Android app was extremely simple, and getting tests to run with Robolectric or the Android instrumentation runner was no problem. I look forward to trying it out more in the future!\n\n","author":"Laura Kogler","date":"2015-11-11","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.0.3 Is Here!","url":"https://blog.jetbrains.com/kotlin/2016/06/kotlin-1-0-3-is-here/","body":"\nWe are delighted to present **Kotlin 1.0.3**. This update is not full of brand new and shiny features, it is more about bug fixes, tooling improvements and performance boosts. That’s why you’ll like it ![\uD83D\uDE09](https://s.w.org/images/core/emoji/72x72/1f609.png) Take a look at the full [change log](https://github.com/JetBrains/kotlin/blob/1.0.3/ChangeLog.md) and issues stats by subsystem:\n\n![Kotlin 1.0.3. Fixed issues](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/Pasted-image-at-2016_06_28-07_25-PM.png) \n\nSpecifically we want to express our gratitude to our contributors whose commits are included in 1.0.3 namely [Yaroslav Ulanovych](https://github.com/yarulan), [Jake Wharton](https://github.com/JakeWharton) and [Kirill Rakhman](https://github.com/cypressious). Kirill has done more than a dozen improvements to formatter and submitted 20+ commits — great job, Kirill, we really appreciate it. Here we also want to thank each and every one of our EAP users who tested and provided their priceless feedback on 1.0.3 prerelease builds.\n\nAlthough this update is not feature-rich, there are several important improvements and features which are worth highlighting here:\n\n## What’s new in the compiler:\n\n* New option `-jdk-home` to specify the JDK against which the code is compiled\n* Options to specify Kotlin language version (`-language-version`) and target Java version (`-jvm-target`) (will have effect in 1.1, added now for forward compatibility)\n* More efficient bytecode (no more iterator in `indices` loop, avoid unnecessary operations with `Unit`)\n* Various improvements to diagnostic messages\n\n## What’s new in the IDE:\n\n* Autosuggestion for Java to Kotlin conversion for Java code copied from browser and other sources outside of the IDE\n ![](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/copypaste.gif)\n* Language injection for strings passed to parameters annotated with @Language. Also predefined Java injections applied in Kotlin code. Read more about using language injections in the [documentation](https://www.jetbrains.com/help/idea/2016.1/using-language-injections.html)\n ![](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/inject.gif)\n\n* Completion now always shows non-imported classes and methods and adds imports automatically when they are selected\n ![](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/import-1.gif)\n\n* Smart completion works after ‘by’ and ‘in’\n ![](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/smart.gif)\n\n* Move Element Left/Right actions work for Kotlin\n ![](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/move.gif)\n\n* _Decompile_ button is now available in Kotlin bytecode toolwindow and for .class files compiled with Kotlin\n ![decompile](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2016/06/decompile.png)\n\n* Now you can navigate from stacktrace to the call site of an inline function\n\n* Inspections and intentions to check and adjust Kotlin configuration in pom.xml files\n* Various Spring support improvements\n\n## How to update\n\nTo update the plugin, use Tools | Kotlin | Configure Kotlin Plugin Updates and press the “Check for updates now” button. Also, don’t forget to update the compiler and standard library version in your Maven and Gradle build scripts.\n\nAs usual, if you run into any problems with the new release, you’re welcome to ask for help on the [forums](https://discuss.kotlinlang.org/), on Slack (get an invite [here](http://kotlinslackin.herokuapp.com/)), or to report issues in the [issue tracker](https://youtrack.jetbrains.com/issues/KT).\n\nLet’s Kotlin!\n\n","author":"Roman Belov","date":"2016-06-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Educational Plugin","url":"http://blog.jetbrains.com/kotlin/2016/03/kotlin-educational-plugin/","body":"\n\nWe always said that Kotlin is really easy to learn. And it is! But it’s not only about the language: learning materials make a difference too. Today we are making another important step in this direction. We are happy to present Kotlin Educational Plugin.\n\n[https://youtu.be/0ponbfQhESY](https://youtu.be/0ponbfQhESY)\n\nKotlin Edu is a plugin for IntelliJ IDEA 2016.1 which lets you take learning courses. A course contains a number of tasks, and every task has several placeholders which you need to fill in correctly to solve it.\n\nAt the moment, there is only one course — the well-known Kotlin Koans, which has been available [online](http://try.kotlinlang.org/koans) for some time and gained considerable popularity among Kotlin learners. The offline versions of the Koans has pretty similar user experience but with all strengths of refactorings and intention actions available in IntelliJ IDEA!\n\nIf you have any questions about Kotlin Koans, feel free to ask them in the **#koans** channel [in our Slack](http://blog.jetbrains.com/kotlin/2016/03/kotlin-educational-plugin/kotlinslackin.herokuapp.com).\n\nP.S. If you want to create your own course, contact us directly via [email](mailto:roman.belov@jetbrains.com).\n\n","author":"Roman Belov","date":"2016-03-17","type":"article","categories":["Kotlin","Education"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Why You Must Try Kotlin For Android Development ?","url":"https://medium.com/@amitshekhar/why-you-must-try-kotlin-for-android-development-e14d00c8084b#.hnaxo3kru","body":"\n![](https://cdn-images-1.medium.com/max/880/1*0M73p2TIq5Wi4lKVaQKZbA.png)\n\n**Kotlin** is a statically typed programming language for the JVM, Android and the browser.\n\n### **Why use Kotlin for Android Development ?**\n\n* **Concise:** Drastically reduce the amount of boilerplate code you need to write.\n* **Safe:** Avoid entire classes of errors such as null pointer exceptions.\n* **Versatile:** Build server-side applications, Android apps or front-end code running in the browser.\n* **Interoperable:** Leverage existing frameworks and libraries of the JVM with 100% Java Interoperability.\n\n### Let’s see the things in more detail ( **Kotlin vs Java** ) **:**\n\n### **Interoperable with Java:** \n\nWhen it comes to give a try to a new language, interoperability is a great thing which can help you. Interoperable means you can reuse any Java class ever written, all Java code can work with Kotlin and vice versa. Learning Kotlin for a Java developer shouldn’t be too hard. Everything you can do with Java, you can do in Kotlin. If you do not know how to do it in Kotlin, then just do it in Java and let the Kotlin plugin convert it to Kotlin. Make sure that you see what happened to your code, so that the next time you can do it yourself.\n\n### **Null Safety:**\n\nKotlin’s type system is aimed at eliminating the danger of null references from code, also known as [**The Billion Dollar Mistake**](https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions).\n\nOne of the most common pitfalls in many programming languages, including Java is that of accessing a member of a null references, resulting in null reference exceptions. In Java this would be the equivalent of a NullPointerException or NPE for short.\n\nIn Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a regular variable of type String can’t hold null:\n\n```kotlin\nvar a: String = \"abc\" \na = null // compilation error\n```\n\nTo allow nulls, you can declare a variable as nullable string, written String?:\n\n```kotlin\nvar b: String? = \"abc\" \nb = null // ok\n```\n\nNow, if you call a method or access a property on a, it’s guaranteed not to cause an NPE, so you can safely say\n\n```kotlin\nval l = a.length\n```\n\nBut if you want to access the same property on b, that would not be safe, and the compiler reports an error:\n\n```kotlin\nval l = b.length // error: variable ‘b’ can be null\n```\n\nBut you still need to access that property, right? There are a few ways of doing that.\n\nChecking for null in conditions:\n\nFirst, you can explicitly check if b is null, and handle the two options separately:\n\n```kotlin\nval l = if (b != null) b.length else -1\n```\n\nSafe Calls:\n\nYour second option is the safe call operator **(?.)**:\n\n```kotlin\nb?.length\n```\n\nThis returns the length of b if b is not null, and null otherwise.\n\n### **Smart Casting:**\n\n```kotlin\n// Java \nif (node instanceOf Leaf) { \n return ((Leaf) node).symbol; \n}\n```\n\n```kotlin\n// kotlin \nif (node is Leaf) { \n return node.symbol; // Smart casting, no need of casting \n}\n```\n\n```kotlin\nif (document is Payable && document.pay()) { // Smart casting \n println(\"Payable document ${document.title} was payed for.\")\n}\n```\n\nKotlin uses lazy evaluation just like in Java. So if the document were not a Payable, the second part would not be evaluated in the first place. Hence, if evaluated, Kotlin knows that document is a Payable and uses a smart cast.\n\n### **Default Arguments:** \n\nDefault arguments are a feature you are missing in Java because it’s just so convenient, makes your code more concise, more expressive, more maintainable and more readable.\n\n```kotlin\nclass Developer(val name: String, \n val age: Int, \n val someValue: Int = 0, \n val profile: String = \"\") { \n}\n```\n\n```kotlin\nval amit = Developer(\"Amit Shekhar\", 22, 10, \"Android Developer\") \nval anand = Developer(\"Anand Gaurav\", 20, 11) \nval ravi = Developer(\"Ravi Kumar\", 26)\n```\n\n### **Named Arguments:** \n\nWhen it comes to readability, Named arguments make Kotlin awesome.\n\n```kotlin\nval amit = Developer(\"Amit Shekhar\", age = 22, someValue = 10, profile = \"Android Developer\")\n```\n\n```kotlin\n// This code is not readable. \nmyString.transform(true, false, false, true, false)\n```\n\n```kotlin\n// the below code is readable as named arguments are present \nmyString.transform( \n toLowerCase = true, \n toUpperCase = false, \n toCamelCase = false, \n ellipse = true, \n normalizeSpacing = false \n)\n```\n\n### **Functional Programming:** \n\nWhile Java evolved to incorporate several functional programming concepts since Java 8, Kotlin has functional programming baked right in. This includes higher-order functions, lambda expressions, operator overloading, lazy evaluation and lots of useful methods to work with collections. \n The combination of lambda expressions and the Kotlin library really makes your coding easier.\n\n```kotlin\nval numbers = arrayListOf(-42, 17, 13, -9, 12) \nval nonNegative = numbers.filter { it >= 0 } \nprintln(nonNegative)\n```\n\n```kotlin\nlistOf(1, 2, 3, 4) // list of 1, 2, 3, 4 \n .map { it * 10 } // maps to to 10, 20, 30, 40 \n .filter { it > 20 } // filters out 30, 40 \n .forEach { print(it) } // prints 30, 40\n```\n\n### **Concise Code:** \n\nWhen you use Kotlin instead of Java, there is a huge reduction of code in your project.\n\nSee it in the example:\n\n```java\n// Java \nButton button = (Button) findViewById(R.id.button); \nbutton.setOnClickListener(new View.OnClickListener() { \n [@Override](http://twitter.com/Override \"Twitter profile for @Override\") \n public void onClick(View view) { \n /* your code */ \n } \n});\n```\n\n```kotlin\n// Kotlin \nval button = findViewById(R.id.fab) as Button \nbutton.setOnClickListener { view -> /* your code */}\n```\n\n","author":"Amit Shekhar","date":"2016-11-10","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"How to Hot Deploy Java/Kotlin classes in Dev","url":"https://hashnode.com/post/how-to-hot-deploy-javakotlin-classes-in-dev-cim3u5oen00fnek53ho7q1t0v","body":"\nOne thing the majority of JVM developers find annoying is having to constantly restart their container. Make a small change, restart Tomcat/Jetty, wait 30+ seconds for code to build / compile (or several minutes in the case of large monolithic projects), see results; repeat.\n\nCompared to Dart which auto-reloads your changes as soon as you hit save, this is very inefficient and kills productivity.\n\nThere's a commercial solution available called [JRebel](http://zeroturnaround.com/software/jrebel/) that aims to solve this problem, I took it for a test drive for a couple of weeks and managed to cut down several hours rapidly increasing my productivity and leaving me with a lot less time to spend on Hashnode.\n\n![title here](https://res.cloudinary.com/hashnode/image/upload/v1458676272/k10afwmauljxts4kdek7.png)\n\nEven though JRebel was saving me a lot of time and pretty much worked out of the box, I just couldn't justify the price tag - at almost $500 a year, converted to Rands, that's about the price of one month's rental in South Africa for a small flat - a bit heavy; all the time I'm saving, I'm paying over to them. Don't get me wrong, I enjoyed using JRebel, but the price tag is just too much when there are other solutions available.\n\nThere is an open-source alternative which works just as well for what I'm using it for - it's called [Spring Loaded](https://github.com/spring-projects/spring-loaded#readme). It probably won't cover everything that JRebel is doing, but I'm mostly busy in Spring, so it's perfect for my needs.\n\nDownload the [jar](http://repo.spring.io/release/org/springframework/springloaded/1.2.5.RELEASE/springloaded-1.2.5.RELEASE.jar) file, throw it somewhere where you won't accidentally delete it, open your `~/.bash_profile` if you're using OSX or on Linux it would typically be your `~/.bashrc` and add the following line followed by restarting your terminal:\n\n`export MAVEN_OPTS=\"-javaagent:/absolute/path/Code/springloaded-1.2.5.RELEASE.jar -noverify\"`\n\nNow when you run your application using the maven jetty plugin or maven tomcat plugin (`mvn jetty:run`), every time you compile a class, it will be reloaded for you without having to do `Ctrl + C` and restarting `mvn jetty:run`. In Eclipse this will happen automatically if you have auto build turned on, in IntellJ, just assign a shortcut to the compile command (I'm using `Cmd + S`), once you're done with your changes, simply hit `Cmd + S` and you can immediately see your changes without restarts.\n\nHappy coding!!\n\n","author":"Jan Vladimir Mostert","date":"2016-03-22","type":"article","categories":["Deploy","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Using Mockito for unit testing with Kotlin (1/x)","url":"http://makingiants.com/blog/using-mockito-for-unit-tests-with-kotlin-1x/","body":"\nDependencies:\n\n```gradle\n\n// Android stuff...\ndependencies {\n //...\n compile \"org.jetbrains.kotlin:kotlin-stdlib:1.0.0\"\n\n testCompile 'junit:junit:4.12'\n testCompile 'org.mockito:mockito-core:2.0.42-beta'\n testCompile('com.squareup.assertj:assertj-android:1.1.1') {\n exclude group: 'com.android.support', module: 'support-annotations'\n }\n}\n\n```\n\n## Little Notes\n\n* All the functions AND PROPERTIES should be open, by default functions and properties are final and mockito cant mock them.\n* **DONT USE** spy functions make tests fail bc of some weird crash (*if someone had use them right comment!!*).\n\n## Example\n\nWe will show:\n\n1. `Settings`: manage settings storage, where to store them and which ones.\n2. `SettingsView`: ...\n3. `SettingsPresenter`: manage the bussiness logic for the settings.\n\nYou may have a class `Settings`:\n\n```kotlin\nopen class Settings(context: Context) {\n val localCache = LocalCache(context)\n\n open var playJustWithHeadphones: Boolean\n get() = localCache.get(\"headphones\", false)\n set(value) = localCache.put(\"headphones\", value)\n}\n```\n\nThen a presenter that use those settings:\n\n```kotlin\nclass SettingsPresenter {\n private var mSettings: Settings? = null\n private var mView: SettingsView? = null\n\n fun onCreate(view: SettingsView, settings: Settings) {\n mView = view\n mSettings = settings\n\n view.setHeadphonesToggleCheck(settings.playJustWithHeadphones)\n }\n}\n```\n\nCheck that mocked Settings class **is open** and mocked var property **is open**\n\nThen the tests passing:\n\n```kotlin\nclass SettingsPresenterTests {\n @Mock lateinit var mockedView: SettingsView\n @Mock lateinit var mockedSettings: Settings\n lateinit var presenter: SettingsPresenter\n\n @Before\n fun setUp() {\n MockitoAnnotations.initMocks(this)\n presenter = SettingsPresenter()\n }\n\n @Test\n fun test_onCreate_updateGui() {\n Mockito.`when`(mockedSettings.playJustWithHeadphones).thenReturn(true)\n presenter.onCreate(mockedView, mockedSettings)\n\n Mockito.verify(mockedView).setHeadphonesToggleCheck(true)\n }\n}\n```\n\n## Notes\n* Using `lateinit` to let the variables be initialized on `@Before` and avoid using `?` or `!!` all over the tests.\n* `SettingsView` and `Settings` are mocked using `MockitoAnnotations`\n","author":"MAKINGIANTS","date":"2016-02-20","type":"article","categories":["Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin for Java Developers: 10 Features You Will Love About Kotlin","url":"http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/","body":"\n# Kotlin for Java Developers: 10 Features You Will Love About Kotlin\n\nKotlin is a statically typed JVM language built by Jetbrains, the makers of the IntelliJ IDE. [Kotlin](https://kotlinlang.org/) is built upon Java and provides useful features such as null-safety, data classes, extensions, functional concepts, smart casts, operator overloading and more.\n\nThis crash course into Kotlin for Java developers demonstrates the most important advantages that Kotlin has over Java and compares some of the language concepts. You can skim the code snippets and boldly marked parts for a quick overview but I recommend you read the whole article (even though it is rather long).\n\n## Contents\n\n1. Why Would I Care About Kotlin?\n2. Null Safety\n3. Data Classes\n4. Extension Functions\n5. Smart Casts\n6. Type Inference\n7. Functional Programming\n8. Objects (aka Easily Create Singletons)\n9. Default Arguments\n10. Named Arguments\n11. Bonus: Enforcing Best Practices\n12. What Now?\n\n## Why Would I Care About Kotlin?\n\nWhat made me particularly interested in Kotlin is the fact that it is **uber-interoperable with Java** and is backed up by Jetbrains and their popular Java IDE IntelliJ. Why did that make me more interested in Kotlin you ask?\n\nWell, interoperability with Java is majorly important because Java has been one of the [most widely used programming language](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) for quite a while now. From a business perspective, this means that most real-world code is written in Java and that companies want to maintain their Java code base as long as possible — typically, the value of the legacy code is in the millions.\n\n**With Kotlin, organizations have the chance to try out a new programming language with minimal risk.** Java files can be converted to equivalent Kotlin files which can then be worked on. Similarly, all types defined in Kotlin (like classes and enums) can be used from within Java just like any other Java type. From a developer point of view, it is great to be able to use the Java libraries that you are used to. You can use Java IO, JavaFX, Apache Commons, Guava and all your own classes right from Kotlin.\n\nAlso, hyperbolically, **a programming language is only as good as its tool support**. This is why the second point speaking in favor of Kotlin for me was that IntelliJ provides built-in language support. It also contains the aforementioned Java-to-Kotlin converter and code generators for Java and JavaScript from Kotlin code.\n\nThese two points also separate Kotlin from other JVM languages such as Scala, Ceylon, Clojure or Groovy.\n\n**Alright, enough talk.** Let’s jump into the actual language features of Kotlin.\n\n## 1) Null Safety\n\n```kotlin\nclass Person {\n val givenName: String = \"\"\n val familyName: String = \"\"\n val address: Address? = null\n}\n```\n\nIn this example, givenName and familyName cannot be null — the program would **fail at compile-time**. You must explicitly make a variable nullable to be able to assign null to it. This is done via the “?” after the variable type. So the address property may be null in the given code.\n\nKotlin also fails at compile-time whenever a NullPointerException may be thrown at run-time — that is, when you try to call a method or reference a property from a nullable type:\n\n```kotlin\nval givenName: String? = null\nval len = givenName.length\n```\n\nIf you try to compile this, the Kotlin compiler will give you an error: “Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type kotlin.String?”. We’ll see how to handle these cases where you _know_ the variable _cannot_ be null in a second.\n\nSo far so good, but what are those safe and non-null asserted calls the compiler is talking about? **Safe calls simply return the value of the call as normally if the callee is not null, and return null otherwise:**\n\n```kotlin\nval givenName: String? = \"\"\nval len = givenName?.length\n```\n\nIn this case, len will be zero as expected. If givenName was null, len would also be assigned null. Thus the return type of givenName?.length is Int?, a nullable integer.\n\nWith non-null asserted calls, you assert to the compiler that you _know_ the variable _cannot_ be null at run-time at the position you use it:\n\n```kotlin\nval givenName: String? = \"Roger\"\nval len = givenName!!.length\n```\n\nTo work with nullable types effectively, the **Elvis operator** comes in handy. It allows you to use a nullable if it is not null and a default value otherwise:\n\n```kotlin\nval text: String? = null\nval len = text?.length ?: -1\n```\n\nIn this example, len will be -1 because the nullable text is in fact null so that the defined default value is used. You may have noticed that this is basically just the widely known _ternary operator_ where the first operand is equal to the expression itself:\n\n```kotlin\nval len = text?.length ?: -1\nval len = text?.length ? text?.length : -1\n```\n\nThese two lines are semantically the same.\n\n## 2) Data Classes\n\nFor simple classes which mainly hold data, you can avoid a lot of boilerplate compared to Java code. Consider the following **typical data class in Java:**\n\n```java\nclass Book {\n private String title;\n private Author author;\n\n public String getTitle() {\n return title;\n }\n\n public void setTitle(String title) {\n this.title = title;\n }\n\n public Author getAuthor() {\n return author;\n }\n\n public void setAuthor(Author author) {\n this.author = author;\n }\n}\n```\n\nLots of boilerplate code that you’ll skip when trying to find out what the class really does. **In Kotlin, you can define the same class concisely in one line:**\n\n```kotlin\ndata class Book(var title: String, var author: Author)\n```\n\nKotlin will also **generate useful hashCode(), equals(), and toString()** implementations. Printing a book will create an output like Book(title=Effective Java, author=Author(name=Joshua Bloch)).\n\n**Challenge**: [Write an Author class](http://try.kotlinlang.org/) that will lead to an output like this!\n\nNot only that, it will also allow you to **easily make copies of data classes:**\n\n```kotlin\nval book = Book(\"Effective Java\", Author(\"Joshua Bloch\"))\nval copy = book.copy()\nval puzzlers = book.copy(title = \"Java Puzzlers\")\nval gof = book.copy(title = \"Design Patterns\", author = Author(\"Gang of Four\"))\n```\n\nYou can change arbitrary properties of the copied object by adding named parameters to the copy() method.\n\nOne more goody is the possibility to use **destructuring declarations** on data classes, retrieving the respective property values:\n\n```kotlin\nval book = Book(\"The Phoenix Project\", Author(\"Kevin Behr\"))\nval (title, author) = book\n```\n\n## 3) Extension Functions\n\nKotlin allows us to **extend the functionality of existing classes without inheriting from them**. This is enabled by extension functions and extension properties. Let’s say you want to extend the GridPane class from the JavaFX GUI framework with a method to retrieve the elements in row i and column j:\n\n```kotlin\nfun GridPane.getElementAt(rowIndex: Int, columnIndex: Int): Node? {\n this.children.forEach {\n if (GridPane.getColumnIndex(it) == columnIndex && GridPane.getRowIndex(it) == rowIndex) {\n return it;\n }\n }\n\n return null;\n}\n```\n\nThere are several things to mention here. First, inside the extension function you can refer to the object on which it was called using “this”. Second, you use Kotlin’s forEach() function on the list of child nodes. This is equivalent to the forEach() method included in Java 8 and allows some functional-style programming. Third, inside the forEach(), you can refer to the current element using the implicit loop variable “it”.\n\nNote that the return type comes after the parentheses containing the parameters and is a nullable Node since the method may return null.\n\n**There’s one thing to be aware of:** If you try to call an extension function with the arguments that are also applicable for an existing member function inside the class, the member will always “win” — meaning that it will take precedence and overshadow your extension function.\n\n## 4) Smart Casts\n\nHow often have you already cast objects where it was actually redundant? More often than you can count I bet, like this:\n\n```java\nif (node instanceof Leaf) {\n return ((Leaf) node).symbol;\n}\n```\n\nThe Kotlin compiler on the other hand is really intelligent when it comes to casts. Meaning: **it will handle all those redundant casts for you**. This is called **smart casts**.\n\nThe equivalent Kotlin code for the code snippet above looks like this:\n\n```kotlin\nif (node is Leaf) {\n return node.symbol;\n}\n```\n\nThe instanceof operator in Kotlin is called “is”. And, more importantly, there is no need to clutter your code with casts that the compiler can actually take care of.\n\nNow this goes much further than just this simple case:\n\n```kotlin\nif (person !is Student)\n return\n\nperson.immatriculationNumber\n```\n\nIn this case, if person were not a student, the control flow would never reach line 4. Accordingly, the Kotlin compiler knows that person must be Student object and performs a smart cast.\n\nLet’s look at some **lazily evaluated conditional expressions**:\n\n```kotlin\nif (document is Payable && document.pay()) { // Smart cast\n println(\"Payable document ${document.title} was payed for.\")\n}\n```\n\nConditionals like these use lazy evaluation in Kotlin, just like in Java. So if the document were not a Payable, the second part would not be evaluated in the first place. Hence, if evaluated, Kotlin knows that document is a Payable and uses a smart cast.\n\nThe same goes for disjunction:\n\n```kotlin\nif (document !is Payable || document.pay() == false) { // Smart cast\n println(\"Cannot pay document ${document.title}.\")\n}\n```\n\nWhen expressions are another place where Kotlin will apply smart casts wherever possible:\n\n```kotlin\nval result = when (expr) {\n is Expr.Number -> expr.value\n is Expr.Sum -> expr.first + expr.second\n is Expr.Difference -> expr.first - expr.second\n is Expr.Exp -> Math.pow(expr.base, expr.exponent)\n}\n```\n\nDepending on the type of the object, you can simply use the respective properties in each when block.\n\nNote: For the example above, the Expr class must be a sealed class with only these exact four subclasses.\n\n## 5) Type Inference\n\n**In Kotlin, you don’t have to specify the type of each variable explicitly, even though Kotlin _is_ strongly typed**. You can choose to explicitly define a data type, for example if you don’t want a small integer to be stored in an Int variables but rather a Short or even a Byte. You can do that using the colon notation where the data type stands behind the variable name:\n\n```kotlin\nval list: Iterable = arrayListOf(1.0, 0.0, 3.1415, 2.718) // Only need Iterable interface\n\nval arrayList = arrayListOf(\"Kotlin\", \"Scala\", \"Groovy\") // Type is ArrayList\n```\n\nYou can choose to use explicit types as in Java but you’re also free to write more concise Python-like variable declarations. Explicit types are useful to reference the most general interface (which you should always do).\n\n## 6) Functional Programming\n\nWhile Java evolved to incorporate several functional programming concepts since Java 8, Kotlin has functional programming baked right in. This includes **higher-order functions, lambda expressions, operator overloading, lazy evaluation** and lots of useful methods to work with collections.\n\nThe combination of lambda expressions and the Kotlin library really makes your day easier when working with collections:\n\n```kotlin\nval numbers = arrayListOf(-42, 17, 13, -9, 12)\nval nonNegative = numbers.filter { it >= 0 }\nprintln(nonNegative)\n```\n\nNote that, when using lambda expressions with a single argument, Kotlin creates an implicit variable called “it” which refers to the lambda expression’s only argument. So the second line above is equivalent to:\n\n```kotlin\nval nonNegative = numbers.filter { it -> it >= 0 }\n```\n\nKotlin provides all essential functional facilities such as **filter, map & flatMap, take & drop, first & last, fold & foldRight, forEach, **reduce_,_ and anything else the pragmatic functional programmer’s heart longs for:\n\n```kotlin\nprintln(numbers.take(2)) // First two elements: [-42, 17]\n\nprintln(numbers.drop(2)) // List without first two elements: [13, -9, 12]\n\nprintln(numbers.foldRight(0, { a, b -> a + b })) // Sum of all elements: -9\n\nnumbers.forEach { print(\"${it * 2} \") } // -84 34 26 -18 24\n\n---\n\nval genres = listOf(\"Action\", \"Comedy\", \"Thriller\")\nval myKindOfMovies: Iterable = genres.filter { it.length <= 6 }.map { it + \" Movie\" }\nprintln(myKindOfMovies) // [Action Movie, Comedy Movie]\n\n```\n\n## 7) Objects (aka Easily Create Singletons)\n\nKotlin has a keyword called _object_ which allows us to define an object, similar to a class. But of course, that object then only exists as a **single instance**. **This is a useful way to create singletons** but the feature is not restricted to only singletons.\n\nCreating an object is as simple as this:\n\n```kotlin\nobject CardFactory {\n\n fun getCard(): Card {\n // ...\n }\n}\n```\n\nAnd you can then use that object like a class with static members:\n\n```kotlin\nfun main(args: Array) {\n val card = CardFactory.getCard()\n}\n```\n\nYou can even **let your objects have superclasses**:\n\n```kotlin\nobject SubmitButtonListener : ActionListener {\n\n override fun actionPerformed(e: ActionEvent?) {\n // Submit form...\n }\n}\n```\n\nThis concept is a powerful extension to the classes, interfaces & enums available in Java because oftentimes, elements of the domain model are inherently objects (they exist only once and thus should always have at most instance at runtime).\n\n## 8) Default Arguments\n\nDefault arguments are a feature I’m dearly missing in Java because it’s just so convenient, makes your code more concise, more expressive, more maintainable, more readable, more everything-that’s-good.\n\nIn Java, you often have to duplicate code in order **define different variants of a method or constructor**. Take a look at this:\n\n```java\npublic class NutritionFacts {\n private final String foodName;\n private final int calories;\n private final int protein;\n private final int carbohydrates;\n private final int fat;\n private final String description;\n\n public NutritionFacts(String foodName, int calories) {\n this.foodName = foodName;\n this.calories = calories;\n this.protein = -1;\n this.carbohydrates = -1;\n this.fat = -1;\n this.description = \"\";\n }\n\n public NutritionFacts(String foodName, int calories, int protein, int carbohydrates, int fat) {\n this.foodName = foodName;\n this.calories = calories;\n this.protein = protein;\n this.carbohydrates = carbohydrates;\n this.fat = fat;\n this.description = \"\";\n }\n\n public NutritionFacts(String foodName, int calories, int protein, int carbohydrates, int fat, String description) {\n this.foodName = foodName;\n this.calories = calories;\n this.protein = protein;\n this.carbohydrates = carbohydrates;\n this.fat = fat;\n this.description = description;\n }\n}\n```\n\nUgh, pretty bad. But it gets even worse if you want to provide more different constructors or add more possible attributes.\n\nThe example above demonstrate the so-called _telescoping anti-pattern_ prevalent in Java. You can improve this design by using the Builder pattern instead.\n\nBut with Kotlin, you can do this even easier using default values for arguments:\n\n```kotlin\nclass NutritionFacts(val foodName: String,\n val calories: Int,\n val protein: Int = 0,\n val carbohydrates: Int = 0,\n val fat: Int = 0,\n val description: String = \"\") {\n}\n```\n\nThis makes each of the parameters with a default value an _optional parameter_. And it actually gives you many more possibilities to invoke the constructor than the Java class above:\n\n```kotlin\nval pizza = NutritionFacts(\"Pizza\", 442, 12, 27, 24, \"Developer's best friend\")\nval pasta = NutritionFacts(\"Pasta\", 371, 14, 25, 11)\nval noodleSoup = NutritionFacts(\"Noodle Soup\", 210)\n```\n\nNote that you may also want to make this sort of class a _data class_ to have methods like equals() and toString() generated for you.\n\n**In short: You get more for less. And keep your code clean at the same time.**\n\n## 9) Named Arguments\n\nDefault arguments become even more powerful in combination with named arguments:\n\n```kotlin\nval burger = NutritionFacts(\"Hamburger\", calories = 541, fat = 33, protein = 14)\nval rice = NutritionFacts(\"Rice\", 312, carbohydrates = 23, description = \"Tasty, nutritious grains\")\n```\n\n**Anyone reading the code knows what’s going on** without having to look at what the parameters mean. This increases readability and can make you more productive when used correctly. For example, this is especially useful when you have several boolean parameters like this:\n\n```kotlin\nmyString.transform(true, false, false, true, false)\n```\n\nUnless you’ve implemented that function 10 seconds ago, there’s no way you know what’s going on here (there’s no guarantee you know even _if_ you’ve implemented it 10 seconds ago).\n\nMake your life (and that of your fellow developers) easier by using named arguments:\n\n```kotlin\nmyString.transform(\n toLowerCase = true,\n toUpperCase = false,\n toCamelCase = false,\n ellipse = true,\n normalizeSpacing = false\n)\n```\n\n## 10) Bonus: Enforcing Best Practices\n\nGenerally, Kotlin enforces many of the best practices you should follow when using Java. You can read about them in Josh Bloch’s book [“Effective Java”](http://www.oracle.com/technetwork/java/effectivejava-136174.html).\n\nFirst of all, the use of **val vs. var** promotes making every variable final that is not supposed to change — while also providing a more concise syntax for it. This is useful when creating immutable objects for example.\n\nThis way, beginners learning the language will also learn to follow this practice right from the start because you tend to think about whether to use **val** or **var** each time and learn to prefer val to var when possible.\n\nNext, Kotlin also supports the principle to either design for inheritance or prohibit it — because in Kotlin, you have to explicitly declare a class as **open** in order to inherit from it. That way, you have to remember to _allow_ inheritance instead of having to remember to _disallow_ it.\n\n## What Now?\n\n**If this overview made you curious** to learn more about Kotlin, you can [check out my 10 beginner tutorial videos for Kotlin](http://petersommerhoff.com/dev/kotlin/kotlin-beginner-tutorial/) or **[go straight to the full course](https://www.udemy.com/kotlin-course/?couponCode=READERSONLY9USD) (with 95% reader discount)**.\n\n**The course is beginner-friendly and starts completely from scratch.** If you already know Java or a comparable language, you’ll still find it a valuable resource to get to know Kotlin.\n\n","author":"Peter Sommerhoff","date":"2015-12-12","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"RxAndroid and Kotlin (Part 1)","url":"https://medium.com/@ahmedrizwan/rxandroid-and-kotlin-part-1-f0382dc26ed8#.bx3rgamfo","body":"\n![](https://d262ilb51hltx0.cloudfront.net/max/2000/1*bTttcFdSLyvWIPg91OaNEw.png)\n\n### RxAndroid and Kotlin (Part 1)\n\nI started with [RxAndroid](https://github.com/ReactiveX/RxAndroid) about a week ago. At first, I didn’t really get it... I mean, I grasped the concept but I didn’t understand where I should be using it. But then after going through a few examples and a few really good articles (links at the end)... I just got it! (to a good extent) And my reaction was pretty much:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*rjlr5GxQIx8o28U5nhtDxg.gif)\n\n##### *Such Rx. Much Reactive. Wow!*\n\nIn short, you can use Rx almost everywhere — but **you shouldn’t**. You should intelligently figure out where it should go. Because in some instances, Rx can be a 100 times more productive and better than normal imperative programming, and in others, it just isn’t necessary.\n\nI’ll demonstrate a few examples in both **Kotlin** and **Java** so that you get an idea of Rx as well as a comparison of the two languages.\n\n> Now if you’re not familiar with Kotlin, then I suggest that you visit these links\n>\n> [Official Kotlin Website](http://kotlinlang.org)\n>\n> [Getting Started on Android](http://kotlinlang.org/docs/tutorials/kotlin-android.html)\n>\n>[Jake Wharton’s Paper on Kotlin](https://docs.google.com/document/d/1ReS3ep-hjxWA8kZi0YqDbEhCqTt29hG8P44aA9W0DM8/edit?usp=sharing)\n>\n> [My Blog](https://medium.com/@ahmedrizwan/android-programming-with-kotlin-6ce3f9b0cbe6) ;)\n>\n> Short Summary : Kotlin is an awesometacular alternative to Java, that works amazingly well on Android. And oh, it's developed by JetBrains!\n>\n>P.S. There are no semicolons in Kotlin. \\*_\\*\n\n#### Rx: The Concept\n\nIf you already have a good concept of Rx, then you can skip this topic. Otherwise... read on!\n\nOk so what is Rx? Well... It’s “reactive programming”... Reactive programming is, in easy words, a programming pattern closely related to the **Observer** **Pattern**. In which, Subscribers “react” to the events emmited by the Observable(s).\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*Oa7zxVaeyF4TO6Mres4E5w.png)\n\n\n![](https://d262ilb51hltx0.cloudfront.net/max/400/1*ATqZ5sek2uAPfZMdmsWHSg.png)\n\n##### *Transformations as the subscriber receives data from observable.*\n\nRx is also a subset of **Functional Programming**. Hence often referred to as Functional Reactive Programming. Because... As the subscribers receive data, they can apply a sequence of **transformations** on them. (Similar to what we can do with Streams in Java 8)\n\nWe can even combine/merge different streams too. It’s that **flexible**! So... For now, just remember there are tons of different things we can do with the data we (the subscribers) receive from observables, on the fly!\n\nNow that the concept is somewhat clear, lets come back to RxJava.\n\nIn Rx, the **subscriber** implements three methods to interact with observable\n\n1. onNext(Data) : Receives the data from Observable\n2. onError(Exception) : Gets called if an exception is thrown\n3. onCompleted() : Gets called when the data stream ends\n\nThis can be compared to the **Iterables** in Java. The difference is that iterables are **pull**-based, and Rx observables are **push**-based as the Observable pushes out data to its subscribers. Here’s the comparison table...\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*6xrzAdP_wa6aR80UrNxiIw.png)\n\n> Another thing to note is that Rx is **asynchronous** in nature, meaning subscribers aren’t going to be waiting for other subscribers to finish. They’ll “asynchronously” process the streams.\n\nSo... Observables push out **streams of data** to their subscribers, and subscribers can consume those streams (with the help of the methods listed above)**.** We can understand “streams” a bit better with the help of [Marble Diagrams](http://rxmarbles.com)...\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*2-sTf0tHsmDlent1HLIhrg.png)\n\n##### *A marble diagram representing two different streams.*\n\nThe cirlces on these streams represent **data objects**. And the arrows represent that the data is flowing in one direction (not referring to the boy band), in an orderly fashion! Have a look at this marble diagram...\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*ju5YD8bRZhdCGmptRQdmlw.png)\n\n##### *A mapping of a stream.*\n\nLike I mentioned before, we can **transform** the data (as well as streams) using [**operators**](https://github.com/ReactiveX/RxJava/wiki/Alphabetical-List-of-Observable-Operators) like map, filter, zip etc. The image above represents a simple mapping. So after this transformation, the subscriber to this stream will get the transformed version of the stream. Cool, right?\n\nI think you should now have a good concept of how things work in Rx, so lets get to the actual implementation.\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*-nTq2bHQbJZctDZZoPnBYQ.png)\n\n#### Implementing Observables\n\nThe first thing we have to do is meditate.\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*I6aMRP_WrXdse197zfBh1Q.jpeg)\n\nAfter that, creating an Observable is not that difficult.\n\nThere are a number of ways we can [create observables](https://github.com/ReactiveX/RxJava/wiki/Creating-Observables), I’ll list down just three here.\n\n1. **Observable.from()** : Creates an observable from an Iterable, a Future, or an Array.\n\n```kotlin\n//Kotlin\nObservable.from(listOf(1, 2, 3, 4, 5))\n//Java\nObservable.from(Arrays.asList(1, 2, 3, 4, 5));\n\n//It will emit these numbers in order : 1 - 2 - 3 - 4 - 5\n//Which should be pretty obvious I guess.\n```\n\n2. **Observable.just()** : Creates observable from an object or several objects\n\n```kotlin\nObservable.just(\"Hello World!\")\n//this will emit \"Hello World!\" to all its subscribers\n```\n\n3. **Observable.create()** : Creates an Observable from scratch by means of a function. We just implement the OnSubscribe interface and tell the observable what it should send to its subscriber(s).\n\n```kotlin\n//Kotlin\nObservable.create(object : Observable.OnSubscribe {\n override fun call(subscriber: Subscriber) {\n for(i in 1 .. 5)\n subscriber.onNext(i)\n\n subscriber.onCompleted()\n }\n})\n```\n\nAnd the java version of the same code...\n\n```java\n//Java\nObservable.create(new Observable.OnSubscribe() {\n @Override\n public void call(final Subscriber \nsubscriber) {\n for (int i = 1; i <= 5; i++)\n subscriber.onNext(i);\n\n subscriber.onCompleted();\n }\n});\n\n//Using the implementation above, we're telling the observer what //it should do when a subscriber subscribes to it. Hence the name //\"onSubscribe\".\n```\n\nThe code I’ve written above is equivalent to the example I wrote for Observable.from() but as you can see, we have full control as to what should be emitted and when should the stream end. I can also send caught exceptions with the use of **subscriber.onError(e)**.\n\nNow we need subscribers!\n\n#### Implementing Subscribers\n\nAfter we have implemented our Observables... All we need is a subscriber! For Android, to subscribe to an observable, we first tell the observable about the threads on which we’re going to be subscribing and observing. RxAndroid gives us [**Schedulers**](https://github.com/ReactiveX/RxJava/wiki/The-RxJava-Android-Module), through which we can specify the thread**s**. So lets take a simple “Hello World” observable for example in which I want the subscription to be done on a **worker thread**, and observation on the **main thread**.\n\n```kotlin\n//Kotlin\nObservable.just(\"Hello World\")\n .subscribeOn(Schedulers.newThread())\n //each subscription is going to be on a new thread.\n .observeOn(AndroidSchedulers.mainThread()))\n //observation on the main thread\n //Now our subscriber!\n .subscribe(object:Subscriber(){\n override fun onCompleted() {\n //Completed\n }\n\n override fun onError(e: Throwable?) {\n //TODO : Handle error here\n }\n\n override fun onNext(t: String?) {\n Log.e(\"Output\",t);\n }\n })\n```\n\n```java\n//Java \nObservable.just(\"Hello World\")\n .subscribeOn(Schedulers.newThread())\n .observeOn(AndroidSchedulers.mainThread())\n .subscribe(new Subscriber() {\n @Override\n public void onCompleted() {\n //Completion\n }\n\n @Override\n public void onError(final Throwable e) {\n //TODO : Handle error here\n }\n\n @Override\n public void onNext(final String s) {\n Log.e(\"Output\",s);\n }\n });\n\n//You can get more info about schedulers and threading here.\n```\n\nSo... What does it do?\n\nWhen you run this code — It’ll display a log message\n\n```\nOutput: Hello World!\n```\n\nAnd that’s it! This is how simple “subscription” is... You can get more details about subscribe [here](http://reactivex.io/documentation/operators/subscribe.html).\n\n#### A Practical Example : Debounce!\n\nOk by now... You know how to create simple observables, right? So let’s do one of my favorite RxExamples... I want to implement this :\n\n![](https://d262ilb51hltx0.cloudfront.net/max/400/1*lyOcKYAvTjDnArAN4rEDNw.gif)\n\nIn this example, I enter text into an EditText and against this text, a response is triggered automatically —in which I print out the text. Now the response could be a call to an API. So if I trigger this call for every character I enter — that would be a waste because I only need the last one, meaning it should trigger a call only when I stop typing — let’s say after 1 second of typing-inactivity.\n\nSo how do we do this in non-reactive programming?\n\nWell it ain’t pretty!\n\n**Non-Reactive Solution**\n\nI use a Timer, and schedule it to call **run**() method after a 1000 milliseconds delay in **afterTextChanged()** method. Oh and don’t forget to add **runOnUiThread**() in there as well. -_-\n\nConceptually it’s not that difficult but the code becomes very cluttered, even more so in Java!\n\nJava version\n\n```java\n//Java\nTimer timer = new Timer();\n\nfinal TextView textView = (TextView) findViewById(R.id.textView);\nfinal EditText editText = (EditText) findViewById(R.id.editText);\n\neditText.addTextChangedListener(new TextWatcher() {\n @Override\n public void beforeTextChanged(CharSequence s, int start, int count,\n int after) {\n }\n\n @Override\n public void onTextChanged(final CharSequence s, int start, int before,\n int count) {\n if (timer != null)\n timer.cancel();\n }\n\n @Override\n public void afterTextChanged(final Editable s) {\n timer = new Timer();\n timer.schedule(new TimerTask() {\n @Override\n public void run() {\n runOnUiThread(new Runnable() {\n @Override\n public void run() {\n textView.setText(\"Output : \" + editText.getText());\n }\n });\n }\n\n }, 1000);\n }\n});\n```\n\nKotlin\n\n```kotlin\n//Kotlin\nvar timer: Timer? = Timer()\n\nval editTextStop = findViewById(R.id.editText) as EditText\neditTextStop.addTextChangedListener(object : TextWatcher {\n override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) = Unit\n\n override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {\n timer?.cancel()\n }\n\n override fun afterTextChanged(s: Editable) {\n timer = Timer()\n timer!!.schedule(object : TimerTask() {\n override fun run() {\n runOnUiThread { textView.setText(\"Output : \" + editTextStop.getText()) }\n }\n }, 1000)\n }\n})\n```\n\n**Reactive Solution**\n\nReactive solution is very boilerplate-free. And there are only 3 steps to it.\n\n1. Create an observable\n2. Add Debounce operator with 1000 Milliseconds (1 second) delay\n3. Subscribe to it\n\nFirst the Java code\n\n```java\n Observable.create(new Observable.OnSubscribe() {\n @Override\n public void call(final Subscriber subscriber) {\n editText.addTextChangedListener(new TextWatcher() {\n @Override\n public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {\n }\n\n @Override\n public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {\n subscriber.onNext(s.toString());\n }\n\n @Override\n public void afterTextChanged(final Editable s) {\n }\n });\n }\n })\n .debounce(1000, TimeUnit.MILLISECONDS)\n .observeOn(AndroidSchedulers.mainThread())\n .subscribe(new Action1() {\n @Override\n public void call(final String s) {\n textView.setText(\"Output : \" + s);\n }\n });\n```\n\n\nNow Kotlin ❤\n\n```kotlin\n Observable.create(Observable.OnSubscribe { subscriber ->\n editText.addTextChangedListener(object : TextWatcher {\n override fun afterTextChanged(s: Editable?) = Unit\n\n override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit\n\n override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int)\n = subscriber.onNext(s.toString())\n })\n }).debounce(1000, TimeUnit.MILLISECONDS)\n .observeOn(AndroidSchedulers.mainThread())\n .subscribe({\n text ->\n textView.text = \"Output : \" + text\n })\n```\n\n\n#### Even Less Boilerplate →RxBindings!\n\nNow for almost no boilerplate, we can use [**RxBindings**](https://github.com/JakeWharton/RxBinding)which has many super-awesome bindings for UI widgets. And it works on both Java and Kotlin! Using bindings, the code becomes...\n\n```java\n //Java with Retrolambda and RxBinding\n RxTextView.afterTextChangeEvents(editText)\n .debounce(1000,TimeUnit.MILLISECONDS)\n .observeOn(AndroidSchedulers.mainThread())\n .subscribe(tvChangeEvent -> {\n textView.setText(\"Output : \" + tvChangeEvent.view()\n .getText());\n });\n```\n\n```kotlin\n //Kotlin with RxBinding\n RxTextView.afterTextChangeEvents(editText)\n .debounce(1000, TimeUnit.MILLISECONDS)\n .observeOn(AndroidSchedulers.mainThread())\n .subscribe { tvChangeEvent ->\n textView.text = \"Output : \" + tvChangeEvent.view().text\n }\n```\n\nAs you would’ve noticed, there’s very little boilerplate and the code is much more to-the-point. If I were to go back to this code in a few months, it would hardly take me a minute to figure out what’s going on. And that is... Priceless!\n\nHere are some awesome resources for Rx that I recommend. Do check these out! I will further play around with Rx+(Kotlin & Java) and complete part 2, so stay tuned and happy coding!\n\n* [Official Rx Page](http://reactivex.io)\n* [Grokking RxJava Series by Dan Lew](http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/)\n* [Android Rx, and Kotlin : A case study](http://beust.com/weblog/2015/03/23/android-rx-and-kotlin-a-case-study/)\n* [Replace AsyncTasks with Rx](http://stablekernel.com/blog/replace-asynctask-asynctaskloader-rx-observable-rxjava-android-patterns/)\n* [PhilosophicalHacker Blog on Rx](http://www.philosophicalhacker.com/2015/06/12/an-introduction-to-rxjava-for-android/)\n* [Implementing EventBus in Rx](http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/)\n* [RxKotlin](https://github.com/ReactiveX/RxKotlin)\n\n","author":"Ahmed Rizwan","date":"2015-06-27","type":"article","categories":["Kotlin","RxAndroid","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Few thoughts about Kotlin and why I like it so much","url":"http://blog.dhananjaynene.com/2016/04/few-thoughts-about-kotlin-and-why-i-like-it-so-much/","body":"\nIt doesn't matter how many languages you have learnt, learning yet another one is always a wonderful experience. I have been working for a couple of months with Kotlin. Have got one app to ready for production state and another in the works.\n\nTo cut to the chase, I am really impressed by this language. As in really really impressed. And so I decided that I should write a few posts that can help readers get a better idea and learn about this language. So I started writing out the series and am already onto the third post now. But as I was writing it, I realised what I was writing was really about the mechanics of the language. Not so much about its spirit. Cos when one gets into the tactical nitty gritty details, one tends to miss the forest for the trees. So I decided to pen that here before I start that series (next week), and here's my few thoughts about why I really enjoy the language.\n\nOne of the reasons there is a lot of enthusiasm with the language is because it can be readily used for programming to the Android platform. That is how I ended up learning it. But very soon, my enthusiasm spread into the desktop/server space where I think Kotlin deserves a shout out for a very very credible effort.\n\n[ EDIT: Deleted a few paragraphs]\n\nSo what does Kotlin bring to the table?\n\n* Runs on the JVM\n* Is extremely good at interoperating with existing java code and libraries.\n* Statically typed (thus far far easier to refactor)\n* Has a bit more evolved type system than Java.\n* Is much safer than Java. Nullability is a first class compiler level construct - something that helps address a large number of likely defects aka the billion dollar bug). There is a lot to write home about here.\n* Has a clear system of distinguishing between mutable and immutable structures. While it doesn't make an opinionated stand in favour of immutability, it gives you the programmer enough helpful constructs to chart your course down that path.\n* Has support for type inference which helps reduce your boiler plate and keeps code shorter\n* Has a wonderful story to tell in terms of it providing programmers an ability to write extension functions to existing classes (or for that matter even primitives).\n* Support for Higher Order Functions, Higher kinded types\n* Support for Android programming and JavaScript execution engine (experimental).\n\nDoes that make it the better language? I personally think it has achieved amongst the best set of tradeoffs that are attractive to me (obviously YMMV). And here's why I enjoy it so much.\n\n* Its expressivity is comparable to and superior than python keeping your code short and sweet\n* It being a statically typed language helps enormously speed up refactoring exercises. Even though I have been using it for only two months, I went through at least two brutal refactoring cycles and found Kotlin code to be a pleasure to change.\n* It is safer, lot lot safer than python / java and delegates one of the most frequent tasks of programming ie. null checking to the compiler. Thats a huge effort of the back along with reduction in number of probable defects. Surely nothing to complain about here. And believe me this is a big big plus point.\n* Uses the JVM which is a fine and fast runtime engine\n* It is easy to learn. I actually went through the reference from start to end in 2 days and was a half decent programmer in about a weeks time. Since then I have written functional libraries for Option, Either, Stack, List, HTTP Clients, XML parsing helper libraries, rather complex X.509 certificate trust chain verifiers and a complete Java FX based app. Have started playing around with more functional constructs such as currying, functors etc. Look forward to working more with typeclasses. I just don't think I could have had such a pace of progress with any other language.\n* It is non opinionated. For XML parsing I wanted to ensure very low memory footprint because I wanted to use it on android. I was able to write a library which heavily used mutation even as it maintained very low memory usage by keeping extra object allocation counts down. For another situation I wanted to use immutable functional paradigm, and Kotlin happily let me create my own Option/Either/List classes and use that paradigm end to end. It doesn't get in your way. And focuses on getting work done.\n* I have been interfacing with a large number of java libraries. The interoperability has been an absolute breeze. It is actually refreshing to go through that experience. Doesn't matter if you are dealing with HTTP client APIs, integrating into a Slack HTTP service, interfacing with Java PKCS API, Kotlin does it easily and safely.\n\nIn a nutshell, I can write code that is safer, shorter, uses better building blocks, is easier to grok, gives me all the nice capabilities such as HOFs, lambdas, pretty competent type system that gives me all the feedback necessary when writing code and makes refactoring a breeze, and interoperates nicely and leverages the JVM universe.\n","author":"Dhananjay Nene","date":"2016-04-15","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin: a new JVM language you should try","url":"https://opencredo.com/kotlin/","body":"\n## Kotlin 1.0 is here\n\n[JetBrains](https://www.jetbrains.com/) (the people behind IntelliJ IDEA) have [recently announced](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/) the first RC for version 1.0 of [Kotlin](https://kotlinlang.org/), a new programming language for the JVM. I say ‘new’, but Kotlin has been in the making for a few years now, and has been used by JetBrains to develop several of their products, including Intellij IDEA. The company [open-sourced](https://github.com/JetBrains/kotlin) Kotlin in 2011, and have worked with the community since then to make the language what it is today.\n\n![Kotlin](https://opencredo.com/wp-content/uploads/2016/02/kronshtadt.jpg)\n\n## What is Kotlin and why you should care\n\nThere is no shortage of [JVM languages](https://en.wikipedia.org/wiki/List_of_JVM_languages) to choose from these days. Kotlin (named after [Kotlin island](https://en.wikipedia.org/wiki/Kotlin_Island), near St. Petersburg, pictured above) positions itself as a pragmatic and easy-to-use alternative to Java, with which it is highly interoperable, to the point where you can mix Kotlin and Java code in the single codebase. The emphasis on interoperability lowers the adoption barrier, which can make Kotlin rather appealing to any Java developer who wished Java was more expressive and less verbose. Kotlin compiles to Java 6-compatible bytecode so you can use the powerful features it offers on older JVM versions (or Android where it has become quite popular already).\n\n## Hello World! with Kotlin\n\nLet’s see some code and compare it with Java and Scala (from which Kotlin has borrowed quite a few language constructs) to get a first impression about the language and highlight a few differences compared to the alternatives.\n\n```kotlin\n// Kotlin\nfun main(args: Array) {\n println(\"Hello, World!\")\n}\n```\n\n```scala\n// Scala\nobject App {\n def main(args: Array[String]) {\n println(\"Hello, world!\")\n }\n}\n```\n\n```java\n// Java\npublic class App {\n public static void main(String[] args) {\n System.out.println(\"Hello, World!\");\n }\n}\n```\n\nYou can observe almost immediately how compact Kotlin’s version is (even compared to Scala). Kotlin benefits from top-level (or package-level) functions that are not members of a class or object, which is perfect for the `main` function. Since package declaration is omitted the function belongs to the default package.\n\nThere are a few language features shown above that make Kotlin programs somewhat similar to Scala ones:\n\n* Type declarations are defined after function argument names, variable names or function/method names\n* the `Unit` return type (equivalent to Java void) is optional\n* `Array` is a regular generic type\n* The `println()` function, and other print functions, are available implicitly\n* semicolons are optional :)\n\n## Type system\n\nKotlin’s type system is close enough to Java’s to provide a good level of interoperability, although it still empowers developers to produce elegant code in a productive way; for instance, type inference removes the need to declare variable types everywhere. A lot of features in Kotlin have been influenced by the [Effective Java](http://www.oracle.com/technetwork/java/effectivejava-136174.html) series, and try to tackle some of the not-so-great elements that Java has inherited from its early days. Kotlin makes it easier to follow best practice, and prevents some of the more questionable practices completely.\n\nThe key features of Kotlin’s type system (compared to Java) are:\n\n\n* every class inherits from type `Any`, which defines only 3 functions (`equals()`, `hashCode()` and `toString()`), compared to quite a few more in Java’s `Object`\n* all [data types](https://kotlinlang.org/docs/reference/basic-types.html) are represented by classes, including numbers (`Int`, `Long`, `Double`, etc.), characters (`Char`) and booleans (`Boolean`)\n* a class’s primary [constructor](https://kotlinlang.org/docs/reference/classes.html#constructors) can be defined as part of the class declaration\n```kotlin\nclass Foo(val bar: String, val baz: Int)\n```\n* the `new` keyword is missing\n```kotlin\nval foo = Foo(\"bar\", 42)\n```\n* there are no static methods and any static code needs to be defined in a [class companion object](https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects)\n* classes and functions are final by default and have to be declared `open` to be overridable\n* any type can be enhanced by using [extension functions](https://kotlinlang.org/docs/reference/extensions.html) to define additional functions/methods (no more `xUtils` classes)\n* [generics](https://kotlinlang.org/docs/reference/generics.html) have been revamped to make working with variance much easier\n* [objects](https://kotlinlang.org/docs/reference/object-declarations.html) can be used to implement the singleton pattern or to avoid the need for anonymous inner classes\n* [data classes](https://kotlinlang.org/docs/reference/data-classes.html) make it trivial to create Java Bean-style data containers\n```kotlin\ndata class Person(val firstName: String, val lastName: String)\n```\n\n## Functional programming\n\nKotlin is not a functional language but provides decent support for FP elements where they make sense in the OO world. It lifts functions to first-class-citizen status and makes using them very easy (the same sadly can’t be said about Java, even in version 8). Kotlin supports [higher-order functions](https://kotlinlang.org/docs/reference/lambdas.html#higher-order-functions) which means that functions can be passed in as arguments to other functions or returned from functions.\n\n```kotln\n// List.map() is an example of a higher-order function\nfun List.map(transform: (T) -> R): List {\n val result = arrayListOf()\n for (item in this)\n result.add(transform(item))\n return result\n}\n```\n\nAdditionally, [lambda expressions](https://kotlinlang.org/docs/reference/lambdas.html#lambda-expression-syntax) and [anonymous functions](https://kotlinlang.org/docs/reference/lambdas.html#anonymous-functions) can be used when function expressions or references are expected.\n\n```kotlin\nval doubled = ints.map { it -> it * 2 }\n```\n\nSome other nice features around working with [functions](https://kotlinlang.org/docs/reference/functions.html#functions) in Kotlin include:\n\n\n* default argument values\n```kotlin\nfun read(b: Array, off: Int = 0, len: Int = b.size()) {...}\n```\n* named arguments\n```kotlin\nread(bytes, len = 100)\n```\n* infix notation\n```kotlin\nval plusOne = value + 1 // plus operator is a function call using infix notation\n```\n* Unit return is optional\n```kotlin\nfun printMe(message: String): Unit { println(message) }\n```\n* single-expression functions\n```kotlin\nfun printMe(message: String): Unit = println(message)\n```\n* tail-recursive functions\n```kotlin\ntailrec fun findFixPoint(x: Double = 1.0): Double = if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))\n```\n\n## Null safety\n\nHandling null references has been quite a chore in Java from the very beginning. In recent versions of the language a few utility classes have been added to make it somewhat more manageable (`Objects` in Java 7 and Optional in Java 8 come to mind), but the language itself doesn’t provide much-needed native support. Kotlin is different as it adopts and further enhances Groovy’s approach to [null-safety](https://kotlinlang.org/docs/reference/null-safety.html) and makes working with object references less of a hassle.\n\nBy default, the compiler will prevent assigning null value to an object reference and you have to explicitly declare a variable as nullable.\n\n```kotlin\nvar a: String = \"abc\"\na = null // compilation error\n\nvar b: String? = \"abc\" // '?' declares variable as nullable\nb = null // ok\n```\n\nWith that initial safety feature in place you can then safely follow nullable object references without worrying about `NullPointerException` (or employing an excessive degree of null-checking). Additionally, the so-called Elvis operator (surely you can see Elvis’ hair do in `?:`) provides a syntactic sugar for defining a default value if a null reference has been encountered.\n\n```kotlin\nval departmentHead = employee?.department?.head?.name ?: \"n/a\"\n```\n\nOn top of that, Kotlin offers safe-casting support, where instead of throwing ClassCastException the expression returns a null value.\n\n```kotlin\nval aInt: Int? = a as? Int\n```\n\n## Collections\n\nUnlike Scala, Kotlin doesn’t provide its own collection framework built from ground up. The rationale behind that choice is Java interoperability. Collections are the bread and butter of software engineering and the team behind Kotlin decided they didn’t want to make it difficult to use Java collections from Kotlin, or to make developers to learn new collection types. [Collections in Kotlin](https://kotlinlang.org/docs/reference/collections.html) reflect those in Java with one difference – Kotlin distinguishes between immutable and mutable collections, favouring immutability (although mutable Java collections are being used behind the scenes).\n\n```kotlin\nval numbers: MutableList = mutableListOf(1, 2, 3)\nval readOnlyView: List = numbers\nprintln(numbers) // prints \"[1, 2, 3]\"\nnumbers.add(4)\nprintln(readOnlyView) // prints \"[1, 2, 3, 4]\"\nreadOnlyView.clear() // -> does not compile\n\nval strings = hashSetOf(\"a\", \"b\", \"c\", \"c\")\nassert(strings.size == 3)\n```\n\nAdditionally, the [collection API in Kotlin](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/index.html) offers a range of easy-to-use extension functions around collection types.\n\n```kotlin\nval items = listOf(1, 2, 3, 4)\nitems.first() == 1\nitems.last() == 4\nitems.filter { it % 2 == 0 } // returns [2, 4]\nitems.filter { it % 2 == 0 } take 1 forEach { println(it) } // prints out 2\nitems.fold(0) { total, current -> total + current } // returns 10\n```\n\nCreating and using maps is quite convenient too.\n\n```kotlin\nval readWriteMap = hashMapOf(\"foo\" to 1, \"bar\" to 2)\nprintln(readWriteMap[\"foo\"])\nval readOnlyView: Map = HashMap(readWriteMap)\nval doubled = readOnlyView.mapValues { entry -> entry.value * 2 }\nfor ((key, value) in doubled) println(\"$key -> $value\")\n```\n\n## Control flow\n\nKotlin offers some improved [control flow constructs](https://kotlinlang.org/docs/reference/control-flow.html), certainly compared with Java. So for instance, the `if ... else` block is an expression (returns a value).\n\n```kotlin\nval max = if (a > b) a else b\n```\n\nThe `switch` operator (as found in C and Java) has been replaced by `when` expression form, similar to pattern-matching in Scala, that also makes a convenient replacement for `if ... else` chains.\n\n```kotlin\nwhen {\n x.isOdd() -> print(\"x is odd\")\n x.isEven() -> print(\"x is even\")\n else -> print(\"x is funny\")\n}\n```\n\nThe `when` expression supports [smart-casts](https://kotlinlang.org/docs/reference/typecasts.html#smart-casts) too, when combined with matching on the type of the when argument.\n\n```kotlin\nval hasPrefix = when(x) {\n is String -> x.startsWith(\"prefix\") // x is automatically casted to String\n else -> false\n}\n```\n\nA `for` loop can iterate over any type that provides an iterator implementing `next()` and `hasNext()`.\n\n```kotlin\nfor (item in collection)\n print(item)\n\nfor ((index, value) in array.withIndex()) {\n println(\"the element at $index is $value\")\n}\n```\n\n## Other features\n\nI think we’ve covered quite a lot already, but there are still a few more features worth highlighting to round up the language overview:\n\n* [string templates](https://kotlinlang.org/docs/reference/basic-types.html#string-templates) (known in Scala as string interpolation) make it easy to format string messages easily by resolving variables and expressions\n\n```kotlin\nval s = \"abc\"\nval str = \"$s.length is ${s.length}\" // evaluates to \"abc.length is 3\"\n```\n* [destructuring](https://kotlinlang.org/docs/reference/multi-declarations.html) allows convenient extraction of data class or collection elements\n```kotlin\nval person = Person(\"Rafal\", 22) // I wish I was 22 again!\nval (name, age) = person\n\nfor ((key, value) in map) {\n // Map.Entry can be destructured too\n}\n```\n* [type checks](https://kotlinlang.org/docs/reference/typecasts.html) support smart-casting\n```koltin\nif (x is String) {\n print(x.length) // x is automatically cast to String\n}\n```\n* [structural equality](https://kotlinlang.org/docs/reference/equality.html#structural-equality) can be checked simply with the `==` operator (no need to use `equals()`)\n* [referential equality](https://kotlinlang.org/docs/reference/equality.html#referential-equality) can be checked with the `===` operator\n* creating [ranges](https://kotlinlang.org/docs/reference/ranges.html) is supported natively\n```koltin\nfor (i in 1..10 step 2) println(i)\n```\n* predefined [operators can be overloaded](https://kotlinlang.org/docs/reference/operator-overloading.html) (so no crazy operators allowed but still quite powerful)\n* all [exceptions](https://kotlinlang.org/docs/reference/exceptions.html) are unchecked (no more forced exception handling)\n* `try` is an expression\n```koltin\nval a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }\n```\n* [type-safe builders](https://kotlinlang.org/docs/reference/type-safe-builders.html) help creating rich DSLs\n```koltin\nhtml {\n head {\n title {+\"HTML built with Kotlin\"}\n }\n // ...\n}\n```\n\nBy now I’m sure you are overloaded with all this Kotlin knowledge, so I will stop here. I hope I was able to showcase the entire host of very powerful capabilities that Kotlin offers. By all means explore [the language reference](https://kotlinlang.org/docs/reference/) to find out more about various language features.\n\n## Java interoperability\n\nOne of the design goals behind Kotlin has always been to stay close enough to Java to lower the barrier to adoption. Obviously, on the other hand the need to stay interoperable limits the the scope to introduce many new features into the language. I think Kotlin has managed to achieve quite a lot without breaking its ties to the Java world.\n\nMost of the [interoperability](https://kotlinlang.org/docs/reference/java-interop.html) aspects revolve around mapping concepts or types between both languages.\n\nFor instance, since Java doesn’t offer null safety support similar to Kotlin, Java types are treated in a special way and called [platform types](https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types). Null checks are relaxed for such types with the risk of `NullPointerExceptions` being thrown at runtime.\n\n```\nval list = ArrayList() // non-null (constructor result)\nlist.add(\"Item\")\nval size = list.size() // non-null (primitive int)\nval item = list[0] // platform type inferred (ordinary Java object)\n\nitem.substring(1) // allowed, may throw an exception if item == null\n\nval nullable: String? = item // allowed, always works\nval notNull: String = item // allowed, may fail at runtime\n```\n\nSimilarly, Java generics are handled in a special way when types are imported to Kotlin and using Java arrays of primitives requires a workaround where specialised classes are used to represent them in Kotlin.\n\nWhen it comes to [Kotlin classes being called from Java](https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html), much of the work required to make them interoperable happens on the Kotlin side. Developers can use an range of annotations to instruct the compiler to produce code that will be usable from Java.\n\n## Tooling\n\nOne of the interesting aspects about Kotlin is that the language has been created by the company behind a popular IDE product. As one might expect IDE support (well, for Intellij IDEA at least) for Kotlin has been very much a part of working on the language itself. The result is a comprehensive [Kotlin support in Intellij IDEA](https://kotlinlang.org/docs/tutorials/getting-started.html) on a par with that for Java. JetBrains also maintains an [Eclipse plugin for Kotlin](https://kotlinlang.org/docs/tutorials/getting-started-eclipse.html) so this open-source IDE should also provide a good level of support.\n\nKotlin creators have resisted the need to redefine much of the external tooling around the language. So for instance Kotlin projects can be built using Maven, Gradle or even Ant so except for the compiler plugin not much else is changing for those coming from the Java background.\n\n## Kotlin ecosystem\n\nThere is a growing community around the language so perhaps not surprisingly one can already find a good selection of open-source libraries and frameworks written in Kotlin. If you want to stick with your favourite Java framework, you don’t have to make a full transition to Kotlin as you can use your existing framework in Kotlin without too much hassle and even mix Java and Kotlin code in a single codebase.\n\nThe official Kotlin website lists several [tools, libraries and frameworks](https://kotlinlang.org/docs/resources.html), covering MVC/Web, HTTP client, dependency injection and text editor support among over things. Also, the [Awesome Kotlin](https://kotlin.link) GitHub website offers a great selection of resources to explore.\n\n## Summary\n\nI believe Kotlin deserves at least a try, especially if you are coming from the Java background. The language brings a lot of good features from Scala and Groovy closer to Java, so you can benefit from the best of both worlds: the vastness of the Java ecosystem with expressiveness and productivity enhanced by constructs and features coming from other languages. If you do want to give Kotlin a go, why don’t you [try it online](http://try.kotlinlang.org/) first or just create a Kotlin project in your favourite IDE and start experimenting with it.\n\nThroughout this post I was covering Kotlin from the perspective of somebody coming from Java as I believe this is a primary expansion area for the new language. It’s worth knowing that Kotlin is also targeting Android development (also Java but still on version 6) as well as (still experimental) JavaScript runtime as an alternative to the JVM. With such a wide range of applications and some great features I reckon Kotlin stands a good chance of attracting quite a few new users.\n\n","author":"Rafal Gancarz","date":"2016-03-03","type":"article","categories":["null","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Gradle Script Kotlin 0.9.0 Release Notes","url":"https://github.com/gradle/gradle-script-kotlin/releases/tag/v0.9.0","body":"\nGradle Script Kotlin 0.9.0 Release Notes\n========================================\n\nGradle Script Kotlin v0.9.0 is another major step forward in usability, bringing improvements to the DSL, IntelliJ experience, performance, and finally automatic detection of Kotlin based builds.\n\nv0.9.0 is expected to be included in the upcoming Gradle 4.0 RC1.\n\nThe features in this release are also available for immediate use within the latest Gradle Script Kotlin distribution snapshot. To use it, upgrade your Gradle wrapper in the following fashion:\n\n $ cd $YOUR_PROJECT_ROOT\n $ gradle wrapper --gradle-distribution-url https://repo.gradle.org/gradle/dist-snapshots/gradle-script-kotlin-4.0-20170518042627+0000-all.zip\n\nUpdates since v0.8.0\n--------------------\n\n * **Automatic detection of Kotlin based builds** ([#37][10037], [#80][10080]). After a little more than an year since the issue was first added to our board this huge usability improvement has finally landed!\n\n No more `rootProject.buildFileName = 'build.gradle.kts'` boilerplate or `settings.gradle` file required in order to enable Kotlin build script! :tada:\n\n * **Default imports for the whole Gradle API** ([#215][100215], [#347][100347]). To make build scripts more concise, the set of default imports now includes the whole Gradle API as documented in the [Default imports section of the Gradle User Guide](https://docs.gradle.org/current/userguide/writing_build_scripts.html#script-default-imports).\n\n * **Improved Gradle API with type safe setters** ([#341][100341]). Kotlin recognizes mutable JavaBean properties only when both the getter and at least one setter agree on the property type.\n\n More than 50 strongly typed setters have been recently added to the Gradle API enabling build scripts to migrate from invocation heavy configuration syntax such as:\n\n ```kotlin\n val someBuild by tasks.creating(GradleBuild::class) {\n setDir(file(\"some/path\")) // NOT RECOGNIZED AS PROPERTY BECAUSE OF UNTYPED SETTER\n setTasks(listOf(\"foo\", \"bar\")) // NOT RECOGNIZED AS PROPERTY BECAUSE OF UNTYPED SETTER\n }\n ```\n\n to the more declarative:\n\n ```kotlin\n val someBuild by tasks.creating(GradleBuild::class) {\n dir = file(\"some/path\")\n tasks = listOf(\"foo\", \"bar\")\n }\n ```\n\n * **Improved project extension accessors with properties** ([#330][100330]). So one can now write `java.sourceSets` instead of `java().sourceSets` as in `0.8.0`.\n\n * **API documentation** ([#209][100209]). A first cut of this important piece of documentation, generated using [Dokka](https://kotlinlang.org/docs/reference/kotlin-doc.html), is now available at https://gradle.github.io/gradle-script-kotlin-docs/api/.\n\n * **IntelliJ improvements**\n\n * **Classpath computation is now asynchronous** ([#249][100249]). And should no longer block the UI (pending a fix to [this IntelliJ issue](https://youtrack.jetbrains.com/issue/KT-17771))\n\n * **Type-safe accessors are correctly included in the classpath given to IntelliJ** ([#340][100340]). Upon changes to the `plugins` block (pending a fix to [this IntelliJ issue](https://youtrack.jetbrains.com/issue/KT-17770))\n\n * **Source code navigation now works for everything Gradle** ([#281][100281]).\n\n ![source-code-navigation](https://cloud.githubusercontent.com/assets/51689/25772994/1fb02b2a-324c-11e7-91aa-8c7e51c86d86.gif)\n\n * **Source code navigation to sources of included Kotlin libraries** ([#96][10096]). As long as there's at least one `buildscript` repository configured that can resolve the Kotlin source artifacts.\n\n * **Miscellaneous**\n\n * **Polished Android Sample** ([#351][100351]). With all the improvements in this release, our [hello-android sample](https://github.com/gradle/gradle-script-kotlin/tree/master/samples/hello-android) is now boilerplate free:\n\n ```kotlin\n buildscript {\n dependencies {\n classpath(\"com.android.tools.build:gradle:2.3.1\")\n classpath(kotlinModule(\"gradle-plugin\"))\n }\n repositories {\n jcenter()\n }\n }\n\n apply {\n plugin(\"com.android.application\")\n plugin(\"kotlin-android\")\n }\n\n android {\n buildToolsVersion(\"25.0.0\")\n compileSdkVersion(23)\n\n defaultConfig {\n minSdkVersion(15)\n targetSdkVersion(23)\n\n applicationId = \"com.example.kotlingradle\"\n versionCode = 1\n versionName = \"1.0\"\n }\n\n buildTypes {\n getByName(\"release\") {\n isMinifyEnabled = false\n proguardFiles(\"proguard-rules.pro\")\n }\n }\n }\n\n dependencies {\n compile(\"com.android.support:appcompat-v7:23.4.0\")\n compile(\"com.android.support.constraint:constraint-layout:1.0.0-alpha8\")\n compile(kotlinModule(\"stdlib\"))\n }\n\n repositories {\n jcenter()\n }\n ```\n\n And it works with the latest Android Studio (2.3.2).\n\n * **Gradle initialization overhead removed** ([#320][100320]). The implementation of type-safe accessors in `0.8.0` added some undue overhead to project configuration even when there was no Kotlin build script involved. This has been fixed.\n\n * **Idiomatic support for Gradle's `PropertyState` and `ConfigurableFileCollection` properties** ([#344][100344]). Via Kotlin delegated properties:\n\n ```kotlin\n open class GreetingPluginExtension(project: Project) {\n\n // Declare a `PropertyState` backing field\n private\n val messageState = project.property()\n\n // Expose `messageState` as the `message` property whose type is inferred as String\n var message by messageState\n\n // Can also be exposed as `Provider` for additional functionality\n val messageProvider: Provider get() = messageState\n\n // `outputFiles` property type is inferred as `ConfigurableFileCollection`\n // with the following behaviour:\n // - getting will always return the original instance\n // - setting will `setFrom` the source\n var outputFiles by project.files()\n }\n ```\n\n Check out the [provider-properties sample](/gradle/gradle-script-kotlin/tree/master/samples/provider-properties) for more information.\n\n * **Better caching behaviour for type-safe accessors** ([#338][338]).\n\n * **Bug fixes**\n\n * **Setting non-existent Kotlin build script in settings.gradle no longer causes the build to fail** ([#302][100302], [#331][100331]). Following standard Gradle behaviour.\n\n * **Generated extension accessor for the `publishing` extension will work as expected** ([#327][100327], [#328][100328]). And defer configuration until necessary.\n\n * **Projects with Kotlin build scripts in `buildSrc` can be edited with the correct classpath in IntelliJ** ([#339][100339]). As build scripts will now be executed in a best-effort manner when computing the classpath.\n\n\n[10037]: https://github.com/gradle/gradle-script-kotlin/issues/37\n[10080]: https://github.com/gradle/gradle-script-kotlin/issues/80\n[100215]: https://github.com/gradle/gradle-script-kotlin/issues/215\n[100347]: https://github.com/gradle/gradle-script-kotlin/issues/347\n[100341]: https://github.com/gradle/gradle-script-kotlin/issues/341\n[100330]: https://github.com/gradle/gradle-script-kotlin/issues/330\n[100209]: https://github.com/gradle/gradle-script-kotlin/issues/209\n[100249]: https://github.com/gradle/gradle-script-kotlin/issues/249\n[100340]: https://github.com/gradle/gradle-script-kotlin/issues/340\n[100281]: https://github.com/gradle/gradle-script-kotlin/issues/281\n[10096]: https://github.com/gradle/gradle-script-kotlin/issues/96\n[100351]: https://github.com/gradle/gradle-script-kotlin/issues/351\n[100320]: https://github.com/gradle/gradle-script-kotlin/issues/320\n[100344]: https://github.com/gradle/gradle-script-kotlin/issues/344\n[100338]: https://github.com/gradle/gradle-script-kotlin/issues/338\n[100302]: https://github.com/gradle/gradle-script-kotlin/issues/302\n[100331]: https://github.com/gradle/gradle-script-kotlin/issues/331\n[100327]: https://github.com/gradle/gradle-script-kotlin/issues/327\n[100328]: https://github.com/gradle/gradle-script-kotlin/issues/328\n[100339]: https://github.com/gradle/gradle-script-kotlin/issues/339\n","author":"Rodrigo B. de Oliveira","date":"2017-05-18","type":"article","categories":["Kotlin","Gradle Script Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"A DSL Workbench with Gradle and Kotlin","url":"http://jonnyzzz.com/blog/2016/03/08/gradle-for-dsl/","body":"\n\nEasy to use. This is one of a main tasks to solve then new tool is created. For the world of DSL this\nmostly mean it should be easy to a end-user to use the tool and to be able to run the tool within\na continuous integration build easily.\n\nI found an elegant way to fiddle a DSL tasks into Gradle to make it easy to use. Next I'll cover an example\nof [TeamCity2DSL](https://github.com/jonnyzzz/TeamCity2DSL) where I implemented this approach.\n\nDomain description\n------------------\n\nI will not cover the domain where [TeamCity2DSL](https://github.com/jonnyzzz/TeamCity2DSL) is\napplied. This deserves a dedicated post(s) (link will be included here).\nAll we need to know about TeamCity2DSL here are\n\n- it provides a way to describe build settings with [Kotlin](https://kotlinlang.org/) DSL\n- the DSL is executed to generate XML settings that TeamCity understands\n- it also generates DSL from existing XML settings from TeamCity\n\nHere goes tricks one need to handle to use the TeamCity2DSL\n\n* download TeamCity2DSL classes\n* have Kotlin sources with DSL complied\n* allow an IDE to be used to author/edit DSL code\n\nThis is vital to provide as easy as possible way to run those tasks. This is where our Gradle plugin is used.\n\nTeamCity2DSL Gradle Plugin\n--------------------------\n\nThe plugin does the following set of tricks\n\n* it setups project repositories and dependencies\n* setups dependency on Kotlin runtime and compiler\n* declares `dsl2xml` and `xml2dsl` tasks\n* adds DSL generation output folder as Kotlin sources\n* introduces a dependency on compilation from `dsl2xml` task\n\n\nA Gradle Plugin Usage Example\n-----------------------------\n\nThis is `build.gradle` script that is only required to have both TeamCity2DSL tasks (`dsl2xml` and `xml2dsl`) supported\n\n```groovy\nbuildscript {\n repositories {\n jcenter()\n mavenCentral()\n maven { url \"https://dl.bintray.com/jonnyzzz/maven\" }\n }\n\n dependencies {\n classpath 'org.jonnyzzz.teamcity.dsl:gradle-plugin:'\n }\n}\n\napply plugin: 'org.jonnyzzz.teamcity.dsl'\n```\n\n*NOTE*. Replace `` with the latest version\nfrom the [maven repository](https://bintray.com/jonnyzzz/maven/teamcity2dsl/view)\n*NOTE2*. We also assume\n[TeamCity project settings XML files](https://confluence.jetbrains.com/display/TCD10/Storing+Project+Settings+in+Version+Control)\nare located in a `.teamcity` folder.\n\n\nIDE Usages\n----------\n\nThe project opens in IntelliJ IDEA. It detects all dependencies, Kotlin, source roots, library sources, etc.\nNo specific requirements here. It *Just Works*. And again an easy-to-use pattern is implemented.\n\nImplementation Details\n======================\n\nI use [Kotlin](https://kotlinlang.org/) in [TeamCity2DSL](https://github.com/jonnyzzz/TeamCity2DSL).\nThe Gradle plugin is implemented with Kotlin as well.\n\nThe first trick is the plugin itself declares a dependency on\n[Kotlin Gradle plugin](https://kotlinlang.org/docs/reference/using-gradle.html). The version of Kotlin\nis selected from plugin dependency. This allows to avoid\nexplicit configuration for Kotlin.\n```groovy\nproject.apply { config ->\n config.plugin(\"java\")\n config.plugin(\"kotlin\")\n}\n```\n\nThe plugin includes DSL dependencies to itself into `compile` configuration. Those jars are predefined and\nwe make Gradle download them from Maven repository.\n```groovy\nval dsl2xml = project.tasks.create(\"dsl2xml\", Dsl2Xml::class.java)\ndsl2xml.dependsOn(project.tasks.getByName(\"classes\"))\n```\n\nNext, we include all `buildScript` block repositories into code repositories. This helps to avoid\nduplicates in repositories declaration.\n```groovy\nproject.buildscript.repositories.forEach { project.repositories.add(it) }\n```\n\nTo add extra source directory we use the following code (that depends on Gradle's Java plugin)\n\n```groovy\nprintln(\"Adding DSL path to Kotlin source set: ${settings.dslPath}\")\nval sourceSets = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets\n\nprintln(\"Source sets: ${sourceSets.names}\")\nsourceSets.getByName(\"main\").java.srcDir( settings.dslPath!!.path )\n```\n\nWe know Kotlin plugin checks Java output path for kotlin sources too. So we depend here only on Java plugin,\nnot on a private API of the Kotlin plugin.\n\nThe task implementation uses a custom classloader (with `null` parent) to avoid bothering Gradle's tasks\nexecution classpath. This is too complicated, from the other hand, to synchronize dependencies\nof TeamCity2DSL and Gradle. In the future we may consider running an external processes for better stability.\n\nFinally\n=======\n\nWe created a Gradle plugin that helps to use a Kotlin DSL.\n\nEverything that is related to the setup and execution of tasks is now packed as a Gradle Plugin\nleading to easy-to-use and easy-to-adopt solution.\n\nThis pattern could be re-used for other applications.\n\nFeel free to try [TeamCity2DSL](https://github.com/jonnyzzz/TeamCity2DSL) for TeamCity project settings domain.\n\n","author":"Eugene Petrenko","date":"2016-03-08","type":"article","categories":["Gradle","DSL","Teamcity2DSL","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1: What’s coming in the standard library","url":"https://blog.jetbrains.com/kotlin/2017/01/kotlin-1-1-whats-coming-in-the-standard-library/","body":"\nJava 9 is coming and brings [Project Jigsaw](http://openjdk.java.net/projects/jigsaw/spec/sotms/) to the table — the Java platform module system. One of the constraints it imposes is that no two modules can declare public API in the same package. The situation, when there are two modules that contribute to the same package, is called “split” package.\n\nWe face this issue with split packages in our runtime artifacts: first, kotlin-runtime and kotlin-stdlib modules share a lot of kotlin.* packages, second, kotlin-runtime and kotlin-reflect share kotlin.reflect package. What we’re going to do to make our artifacts more friendly to the module system:\n\n1. We merge kotlin-runtime and kotlin-stdlib into the single artifact kotlin-stdlib. Also we’re going to rename kotlin-runtime.jar, shipped in the compiler distribution, to kotlin-stdlib.jar, to reduce the amount of confusion caused by having differently named standard library in different build systems.\n That rename will happen in two stages: in 1.1 there will be both kotlin-runtime.jar and kotlin-stdlib.jar with the same content in the compiler distribution, and in 1.2 the former will be removed.\n2. In kotlin-reflect module we move all API from kotlin.reflect to kotlin.reflect.full package. Kotlin 1.1 will have the former API deprecated with the replacements suggested, and it will be removed eventually in 1.2.\n Note that this change will affect only extension functions and properties provided by kotlin-reflect for reflection interfaces and a couple of exception classes. Reflection interfaces themselves are located in the standard library and won’t be moved.\n\nIf you use maven or gradle and depend on kotlin-stdlib, you won’t need to change anything. If you depend on kotlin-runtime, you should replace that dependency with kotlin-stdlib.\n\n## New Standard Library API in 1.1\n\nHere we introduce new functions and classes that are going to be published in Kotlin 1.1.\n\nIf you have already tried these new bits in Kotlin 1.1-Beta or in earlier releases and have some feedback, do not hesitate to share it in our [forum](https://discuss.kotlinlang.org/), [slack](https://kotlinlang.org/community.html) or [issue tracker](https://youtrack.jetbrains.com/issues/KT).\n\n### takeIf() and also()\n\nThese are two general-purpose extension functions applicable to any receiver.\n\n`also` is like `apply`: it takes the receiver, does some action on it, and returns that receiver.\nThe difference is that in the block inside `apply` the receiver is available as `this`,\nwhile in the block inside `also` it’s available as `it` (and you can give it another name if you want).\nThis comes handy when you do not want to shadow `this` from the outer scope:\n\n```kotlin\nfun Block.copy() = Block().also { it.content = this.content }\n```\n\n`takeIf` is like `filter` for a single value. It checks whether the receiver meets the predicate, and\nreturns the receiver, if it does or `null` if it doesn’t.\nCombined with an elvis-operator and early returns it allows to write constructs like:\n\n```kotlin\nval outDirFile = File(outputDir.path).takeIf { it.exists() } ?: return false\n// do something with existing outDirFile\n\nval index = input.indexOf(keyword).takeIf { it >= 0 } ?: error(\"keyword not found\")\n// do something with index of keyword in input string, given that it's found\n```\n\n### groupingBy()\n\nThis API is to group a collection by key and fold each group in the same time. It consists of two parts: `groupingBy` function, and terminal operations — `fold`, `reduce`, `eachCount`.\n\nFirst you invoke `collection.groupingBy { key }` function, which just returns a `Grouping` instance binding the provided key selector to the collection of elements. Then you call one of folding operations available for `Grouping`, which iterates the collection and populates the resulting map with the result of folding elements in each group.\n\nFor example, it can be used to count the frequencies of characters in a text:\n\n```kotlin\nval charFrequencies: Map = text.groupingBy { it }.eachCount()\n```\n\n### minOf() and maxOf()\n\nThese functions can be used to find the lowest and greatest of two or three given values, where values are primitive numbers or `Comparable` objects. There is also an overload of each function that take an additional `Comparator` instance, if you want to compare objects that are not comparable themselves.\n\n```kotlin\nval list1 = listOf(\"a\", \"b\")\nval list2 = listOf(\"x\", \"y\", \"z\")\nval minSize = minOf(list1.size, list2.size)\nval longestList = maxOf(list1, list2, compareBy { it.size })\n```\n\n### Map.getValue()\n\nThis extension on `Map` returns an existing value corresponding to the given key or throws an exception, mentioning which key was not found.\nIf the map was produced with `withDefault`, this function will return the default value instead of throwing an exception.\n\n```kotlin\nval map = mapOf(\"key\" to 42)\n// returns non-nullable Int value 42\nval value: Int = map.getValue(\"key\")\n// throws NoSuchElementException\nmap.getValue(\"key2\")\n\nval mapWithDefault = map.withDefault { k -> k.length }\n// returns 4\nval value2 = mapWithDefault.getValue(\"key2\")\n```\n\n### Map.minus() operator\n\nIn Kotlin 1.0 you could easily get a copy of a read-only Map with a new key-value pair inserted with the extension operator `Map.plus()`. However to remove a key from the map you have to resort to less straightforward ways to like `Map.filter()` or `Map.filterKeys()`.\nNow `Map.minus()` operator fills this gap. There are 4 overloads available: for removing a single key, a collection of keys, a sequence of keys and an array of keys.\n\n```kotlin\nval map = mapOf(\"key\" to 42)\nval emptyMap = map - \"key\"\n```\n\n### Array-like List instantiation functions\n\nSimilar to the `Array` constructor, there are now functions that create `List` and `MutableList` instances and initialize each element by calling a lambda:\n\n```kotlin\nList(size) { index -> element }\nMutableList(size) { index -> element }\n```\n\n### String to number conversions\n\nThere is a bunch of new extensions on the String class to convert it to a number without throwing an exception on invalid number:\n`String.toIntOrNull(): Int?`, `String.toDoubleOrNull(): Double?` etc.\n\n```kotlin\nval port = System.getenv(\"PORT\")?.toIntOrNull() ?: 80\n```\n\nNote that these functions will box resulting numbers before returning them, since the return type is nullable, and nullable numbers are represented as boxed values.\n\nAlso integer conversion functions, like `Int.toString()`, `String.toInt()`, `String.toIntOrNull()`,\neach got an overload with `radix` parameter, which allows to specify the base of conversion (2 to 36).\n\n### onEach()\n\n`onEach` is a small, but useful extension function for collections and sequences, which allows to perform some action, possibly with side-effects, on each element of the collection/sequence in a chain of operations.\nOn iterables it behaves like `forEach` but also returns the iterable instance further. And on sequences it returns a wrapping sequence, which applies the given action lazily as the elements are being iterated.\n\n```kotlin\ninputDir.walk()\n .filter { it.isFile && it.name.endsWith(\".txt\") }\n .onEach { println(\"Moving $it to $outputDir\") }\n .forEach { moveFile(it, File(outputDir, it.toRelativeString(inputDir))) }\n```\n\n### Map.toMap() and Map.toMutableMap()\n\nThese functions can be used for easy copying of maps:\n\n```kotlin\nclass ImmutablePropertyBag(map: Map) {\n private val mapCopy = map.toMap()\n}\n```\n\n### Abstract collections\n\nThese abstract classes can be used as base classes when implementing Kotlin collection classes.\nFor implementing read-only collections there are `AbstractCollection`, `AbstractList`, `AbstractSet` and `AbstractMap`, and for mutable collections there are `AbstractMutableCollection`, `AbstractMutableList`, `AbstractMutableSet` and `AbstractMutableMap`.\nOn JVM these abstract mutable collections inherit most of their functionality from JDK’s abstract collections.\n","author":"ilya.gorbunov","date":"2017-01-24","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1-M04 is here!","url":"https://blog.jetbrains.com/kotlin/2016/12/kotlin-1-1-m04-is-here/","body":"\nWe are glad to present you the fourth milestone of the upcoming Kotlin release. We’re wrapping up the development of the version 1.1, with the final release planned for Q1 2017. Most features are already in decent shape, so it is a good time to try it and give us your feedback. We will appreciate it a lot!\n\nAs with other milestone releases, we give **no backwards compatibility guarantees** for new language and library features. Anything introduced in milestone releases of 1.1 is **subject to change** before the final 1.1 release.\n\nPlease do share your feedback regarding the new features or any problems that you may run into with this release, via [YouTrack](https://youtrack.jetbrains.com/issues/KT), [forums](https://discuss.kotlinlang.org) and [Slack](http://kotlinlang.slack.com/).\n\nThis milestone brings a significant rework of coroutine syntax and semantics, making coroutines simpler and more flexible. It also contains standard library enhancements, new language features and compiler plugins, numerous features and improvement in the JS backend, and many other fixes and updates. \nThe new release also includes all features introduced in the [Kotlin 1.0.6](https://discuss.kotlinlang.org/t/kotlin-1-0-6-eap/2117/10), including updates for compatibility with **Android Studio 2.3 Beta 1**.\n\nThe full changelog is available [here](https://github.com/JetBrains/kotlin/blob/1.1-M04/ChangeLog.md) and some key changes are listed below: \n\n## Coroutines\n\nWe have significantly re-thought the coroutines design, making it simpler, composable and more powerful:\n\n* All suspending and coroutine builder functions now have intuitive signatures (no more weird transformations to memorise).\n* There is only one basic language concept of suspending functions and the corresponding suspending function types. The special `coroutine` keyword was dropped. The coroutine is now simply an instance of a suspendable computation that is started using `startCoroutine` function from the standard library.\n* Complex suspending functions can be composed out of more primitive suspending functions. In this release they can tail-call other suspend functions, but this restriction will be lifted in the future.\n* Suspending functions can be defined to wrap any callback-style API and can be freely used inside any asynchronous coroutine. The controllers are not needed anymore. The `generate` and `yield` pair, that builds synchronous sequences, restricts suspensions inside generate blocks using `@RestrictsSuspension` annotation.\n* Type inference for coroutines is now implemented. You can omit types in most use-cases for coroutine builders and the types will be inferred automatically.\n\nThe classical `await` suspending function can now be implemented via a tail-call to the `suspendCoroutine` suspending function that is a part of the standard library:\n\n```kotlin\nsuspend fun await(f: CompletableFuture): T =\n suspendCoroutine { c: Continuation ->\n f.whenComplete { result, exception ->\n if (exception == null) // the future has been completed successfully\n c.resume(result) \n else // the future has been completed with an exception\n c.resumeWithException(exception)\n }\n }\n```\n\nThe corresponding builder is called `async` and implemented via the `startCoroutine` function:\n\n```kotlin\nfun async(block: suspend () -> T): CompletableFuture {\n val future = CompletableFuture()\n block.startCoroutine(completion = object : Continuation {\n override fun resume(value: T) {\n future.complete(value)\n }\n override fun resumeWithException(exception: Throwable) {\n future.completeExceptionally(exception)\n }\n })\n return future\n}\n```\n\nAnd they can be used together to write a more naturally-looking code with futures:\n\n```kotlin\nasync {\n val original = asyncLoadImage(\"...original...\") // creates a Future\n val overlay = asyncLoadImage(\"...overlay...\") // creates a Future\n ...\n // suspend while awaiting the loading of the images\n // then run `applyOverlay(...)` when they are both loaded\n return applyOverlay(original.await(), overlay.await())\n}\n```\n\nHowever, futures are just one of many supported use-cases for coroutines. The full overview of the coroutine implementation and their usage samples are available in the revised [KEEP document](https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md).\n\nWe think that now we have got a great design of coroutines for Kotlin, but we realize that it has not been battle-tested enough. Therefore we are going to release it in 1.1 under an opt-in incubation flag. Starting from this milestone you’ll get “This feature is experimental: coroutines” warning when using coroutines. You can turn off this warning with `-Xcoroutines=enable` compiler flag or disable this features with `-Xcoroutines=error` compiler flag. The corresponding setting is also available under Kotlin compiler settings in the IDEA. To set this option for a gradle project you can add `kotlin.coroutines=enable` or `kotlin.coroutines=error` to local.properties file at the root of project.\n\nIf you are using [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) library please use updated version `0.2-alpha-1`, adapted to the newest changes in the coroutines design. This version also introduces `yieldAll` method in the generate scope. Please see the [readme file](https://github.com/Kotlin/kotlinx.coroutines/blob/master/README.md) for further details.\n\n## Language features\n\n### Type for properties can be inferred from getter\n\nFor example in the code below the type for the property `foo` will be inferred as `String`. See the issue [KT-550](https://youtrack.jetbrains.com/issue/KT-550) for some more details.\n\n```kotlin\nval foo get() = \"\"\n```\n\n### Floating point related features, fixes and improvements\n\nFloating point number comparisons now use IEEE 754 compliant comparison where the type is known statically to be `Double` or `Float`. For ranges of floating point numbers we’ve introduced specialized `ClosedFloatingPointRange` interface, which provides its own comparison method, so that extension operations employing ranges, like `coerceIn`, could be implemented on top of that. Its instances are obtained with the operator `..` invoked on two `Float` or `Double` values. See [KT-4481](https://youtrack.jetbrains.com/issue/KT-4481) and [KT-14651 for details.](https://youtrack.jetbrains.com/issue/KT-14651)\n\n### Interception of delegated property binding\n\nIt is possible now to intercept delegate to property binding using the `provideDelegate` operator. \nFor example, if we want to check property name before binding, we can write something like this:\n\n```kotlin\nclass ResourceLoader(id: ResourceID) {\n operator fun provideDelegate(thisRef: MyUI, property: KProperty<*>): ReadOnlyProperty {\n checkProperty(thisRef, property.name)\n ... // property creation\n }\n\n private fun checkProperty(thisRef: MyUI, name: String) { ... }\n}\n\nfun bindResource(id: ResourceID): ResourceLoader { ... }\n\nclass MyUI {\n val image by bindResource(ResourceID.image_id)\n val text by bindResource(ResourceID.text_id)\n}\n```\n\nHere method `provideDelegate` will be called in constructor initializer for class `MyUI`. So, we can check property consistency at the moment of creation. Earlier such checks were only possible at the moment of calling getter or setter.\n\nUnfortunately, the feature is not yet properly documented, but you can use [this draft document](https://github.com/orangy/KEEP/blob/fabb56360f2d7a293ac720cace89cd445da3c919/proposals/attach-to-property.md#createdelegate) as an initial reference.\n\n### Enhanced nullability of some JDK methods\n\nSome functions in JDK have a nullability contract defined in the documentation, some do not accept null values, some never return null, and yet others can return null sometimes. \nUnfortunately, the JDK does not use any annotations to express such contracts and only states them in the docs. Once before 1.0 we used an external annotations artifact for the JDK which could be supplied to the compiler to alter the signatures of JDK functions, but that approach wasn’t reliable enough.\n\nNow we’re introducing another approach: embedding the information required to enhance the JDK signatures directly into the compiler. As a first step we cover the nullability of a small subset of the API:\n\n* `java.util.Optional` factory and member functions:\n * `of`: that doesn’t allow null values\n * `ofNullable`, it takes a nullable value, and return an `Optional` of non-nullable type.\n * `get` always return non-nullable value.\n* `java.lang.ref.Reference` and all of its inheritors, like `WeakReference` and `SoftReference`:\n * `get` returns a nullable value, as it can become null at any moment if the referenced object is garbage collected.\n* default methods of JDK’s `Iterator`, `Iterable`, `Collection`, `List`, `Map` which are exposed as platform-dependent functions of Kotlin builtin collection interfaces.\n* java functional types, now they have non-platform types in their invocation methods when they’re constructed with non-platform types.\n\nThese enhancements are safe in most cases. In particular, they are safe when the enhanced type becomes more specific (non-nullable) in return position or more general (nullable) in parameter position. But when the type is changed in the opposite direction, the change will be breaking. \nWe strive not to introduce such breaking enhancements unless not respecting the correct nullability would lead to an exception in runtime. So for example `Optional.of` now takes a non-nullable argument which is more restrictive, but trying to pass `null` to that method would result in an exception anyway. \nOn the other hand, we decided not to specify the correct nullability for `File.listFiles` which actually can return null sometimes, because in most cases there’s no meaningful fallback other than to throw another exception.\n\n### Other changes\n\n* Problem of using a non-public member from a public inline function could now be resolved with the `@PublishedApi` annotation. When it’s applied on an _internal_ member, it becomes effectively public and available to invoke from a public inline function.. See [KT-12215](https://youtrack.jetbrains.com/issue/KT-12215) for details.\n* `const val` is now inlined at the call site (see [KT-11734](https://youtrack.jetbrains.com/issue/KT-11734))\n* SAM conversions have now the same priority in overload resolution as regular members. That fixes [KT-11128](https://youtrack.jetbrains.com/issue/KT-11128) and alike.\n* We consider our choice of `mod` name for `%` (remainder) operator a mistake with some not so nice consequences (see e.g. [KT-14650](https://youtrack.jetbrains.com/issue/KT-14650)). Therefore we decided to introduce `rem` operator, deprecate the `mod` and provide all tools to make this transition smooth.\n\n## Standard library\n\n### String to number conversions\n\nThere is a bunch of new extensions on the `String` class to convert it to a number without throwing an exception on invalid number: `String.toIntOrNull(): Int?`, `String.toDoubleOrNull(): Double?` etc. \nBeware that these functions will box resulting numbers before returning them, as the return type assumes it.\n\nAlso integer conversion functions, like `Int.toString()`, `String.toInt()`, `String.toIntOrNull()`, each got an overload with `radix` parameter, which allows to specify the base of conversion.\n\nWe would like to thank [Daniil Vodopian](https://github.com/voddan) for his substantial contribution to the development of these functions.\n\n### onEach\n\n`onEach` is a small, but useful extension function for collections and sequences, which allows to perform some action, possibly with side-effects, on each element of the collection/sequence in a chain of operations. \nOn iterables it behaves like `forEach` but also returns the iterable instance further. And on sequences it returns a wrapping sequence, which applies the given action lazily as the elements are being iterated.\n\nThanks to [Christian Brüggemann](https://github.com/cbruegg) for the initial prototype.\n\n## JavaScript backend\n\n### `external` instead of `@native`\n\nFrom this milestone `@native` annotation becomes deprecated and instead you have to use `external` modifier. \nUnlike the JVM target, the JS one permits to use `external` modifier with classes and properties. \nNote, that you don’t need to mark members of `external` classes as `external`: this modifier \nis automatically inherited by the members. So, instead of\n\n```kotlin\n@native fun alert(message: Any?): Unit {}\n```\n\nyou can write\n\n```kotlin\nexternal fun alert(message: Any?)\n```\n\n### Improved import handling\n\nYou can now describe declarations which should be imported from JavaScript modules more precisely. \nIf you add `@JsModule(\"\")` annotation on an external declaration it will be properly imported to a module system (either CommonJS or AMD) during the compilation. For example, with CommonJS the declaration will be imported via `require(...)` function. \nAdditionally, if you want to import a declaration either as a module or as a global JavaScript object, you can use `@JsNonModule` annotation\n\nLet’s see the full example below. You can import jQuery library to a Kotlin source file like this:\n\n```kotlin\n@JsModule(\"jquery\")\n@JsNonModule\n@JsName(\"$\")\nexternal abstract class JQuery {\n fun toggle(duration: Int = 0): JQuery\n fun click(handler: (Event) -> Unit): JQuery\n}\n\n@JsModule(\"jquery\")\n@JsNonModule\n@JsName(\"$\")\nexternal fun JQuery(selector: String): JQuery\n```\n\nIn this case, JQuery will be imported as a module named `jquery` and alternatively, it can be used as a `$`-object, depending on what module system Kotlin compiler is configured to use.\n\nYou can use these declarations in your application like this:\n\n```kotlin\nfun main(args: Array) {\n JQuery(\".toggle-button\").click {\n JQuery(\".toggle-panel\").toggle(300)\n }\n}\n```\n\nYou can check the generated JS code for this snippet for the CommonJS and “plain” module systems [here](https://gist.github.com/ligee/50d30ad9bca5ea925ff7d913ff232004).\n\n## How to Try It\n\n**In Maven/Gradle:** Add [http://dl.bintray.com/kotlin/kotlin-eap-1.1](http://dl.bintray.com/kotlin/kotlin-eap-1.1) as a repository for the build script and your projects; use 1.1-M04 as the version number for the compiler and the standard library.\n\n**In IntelliJ IDEA:** Go to _Tools → Kotlin → Configure Kotlin Plugin Updates_, then select “Early Access Preview 1.1” in the _Update channel_ drop-down list, then press _Check for updates_.\n\nThe **command-line compiler** can be downloaded from the [Github release page](https://github.com/JetBrains/kotlin/releases/tag/v1.1-M04).\n\n**On [try.kotlinlang.org](http://try.kotlinlang.org)**. Use the drop-down list at the bottom-right corner to change the compiler version to 1.1-M04.\n\nMerry Kotlin!\n\n","author":"Ilya Chernikov","date":"2016-12-21","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Creating an AndroidWear watchface using Kotlin","url":"https://medium.com/@robj.perez/creating-an-androidwear-watchface-using-kotlin-e5f725813fa9#.xcftwvys6","body":"\n### Creating an AndroidWear watchface using Kotlin\n\n![](https://d262ilb51hltx0.cloudfront.net/max/600/1*78W0Fk8Ca3OGCdZiebTvSw.png)\n\nLast week we released our [latest watch face](https://play.google.com/store/apps/details?id=com.meronapps.lcdmodularwatchface) for Android Wear, and it is a little bit special, it is the first done using something different from Java. It is entirely written in Kotlin. In this post I would like to share our experiences while building it and how doing in the language created by Jetbrains has improved the development process.\n\nTo add a little bit of context, [we are](http://meronapps.com) a Madrid based small company which, among other things, have been doing a lot of wearables applications, we have worked with Pebble, Sony smartwatch, Samsung’s Tizen, Apple Watch and, of course, Android Wear. In our Google’s OS take on watches, this is our seventh watch face, and all of them were developed using the ubiquitous Java.\n\nIf you don’t know Kotlin, it is a open sourced language designed by Jetbrains, yes, they are the ones behind the powerful IntelliJ Idea, the IDE which powers Android Studio. Kotlin is yet another language for the JVM and brings a lot of fresh air to JVM development. Since it does not uses any “strange” things like AOT compilation or bytecode generation, it is fully interoperable with Java and it works wherever Java works, so it does in Android. If you haven’t took it a look, I recommend you to do it, you can get started at [https://kotlinlang.org/](https://kotlinlang.org/)\n\nOnce we did the introductions, let’s go to the heart of the post, the learnings from our watch face development.\n\n#### Ready for Production\n\nDuring the development of the watchface, Kotlin 1.0 was officially released, but truth is said, everything worked perfectly. Developer tools are formed by several packages, and all of them worked pretty well even though they were beta versions, which became stable afterwards.\n\nAndroid Studio Kotlin plugin works pretty well, it helps you with code completion, syntax highlighting, code navigation, code conversion from Java and all the candies you can expect from a mature IDE.\n\nKotlin’s Android gradle plugin was perfectly integrated with Android, you just click on Run, and it works on your phone, zero problems. There is just a single issue, the new feature from the Android build tools, Instant Run, doesn’t work yet. This was somehow expected, if you know how it works by patching the dex file, it is expected that the compilation process of Kotlin might has some problems with it.\n\nSince we started using Kotlin when it was about to reach 1.0, the language itself is pretty stable, the syntax changes, if any, didn’t have any impact in our code, we didn’t have any problems the compiler and standard library either.\n\n#### Fully interoperable with Java\n\nOne of the pillars of this language is that it is fully compatible with all the existing Java code, it means that you can use all Android libraries, and if you already have libraries and code, you can call it without any problems nor changes.\n\nThis feature is key to adopt Kotlin in your new developments, in fact, we started by using some of our libraries which we have developed for all of our projects. What it happened, is that we converted all those libraries to Kotlin and now our previous projects are using a library written using kotlin code.\n\n#### No more _if (foo != null)_ and less NullPointerException\n\nIf you are a java developer, you probably have suffered the curse of writing _if (foo != null)_ thousand of times, and when you forget it, a _NullPointerException_ will remind you to write it.\n\nKotlin tries to eliminate this infamous check with some syntax sugar. If a variable can be null, you need to explicit say it, you cannot assign a null to a _String_ type, but you can do it to a _String?_. (note the question mark at the end). You cannot dereference a _?_ variable without explicitly unwrapping it either by using !! or by using a _?_ at the end. If a variable is null and you use a _?_ at the end, it won’t crash with a NPE. That means you can write _rectangle?.size?.width?_, if rectangle or size is null, nothing happens.\n\n#### Fill your listeners using cool lambdas\n\nWhen it comes to java, you know that you are going to put in use you typing skills. Chances are that you are using a modern IDE and it will save you a little bit from that pain, but all the boilerplate code is there.\n\nIf you write Applications which respond to events like an Android application or an UI app, this is particularly notorious when you need to write control _Listeners_. Kotlin does magic in this side, if you need to implement an Interface which has only one method, you can use a Kotlin lambda to do it, saving you hundreds of characters and making your code more expressive with less useless decorations. Let’s see an example to show this better\n\n```java\n// Java (129 characters of boilerplate code)\n\nview.setOnClickListener(new OnClickListener() {\n @Override\n public void onClick(View v) {\n // Do something cool\n }\n});\n```\n\n```kotlin\n// Kotlin (37 characters to do exactly the same)\n\nview.onClick { // Do something cool }\n```\n\n#### No more findViewById\n\nThis point is specifically related with Android. Kotlin has a library called Android Extensions which will save you from typing useless code.\n\nWhen I started in Android Programming some years ago, I hated why I needed to write so many _findViewById()_ and hated more the typecast of that method. For non Android programmers, that method returns a generic _View_ and you probably will need to cast it to a _Button_ or a _TextView_ to do something useful with it. Among other cool things, the Android Extensions library allows you to use any view from a layout just by using its id. You only need to import the layout like it was another class and all ids will be visible in your code magically.\n\n```java\n// Java\n\nTextView tv = ((TextView)findViewById(R.id.my_textview)).setText(“Java y u make me write so much!”)\n```\n\n```kotlin\n// Kotlin\n\nimport kotlinx.android.synthetic.main_layout.*\nmy_textview.text = \"isn’t kotlin cool?\"\n```\n\n#### Syntax sugar\n\nKotlin has a lot more to offer in terms of making your code more readable and allowing you to type less. Java getters and setters are automatically converted to properties, instead of write _person.getName()_ or _setName(“”)_, Kotlin allows you call that java code by writing _person.name_ or _person.name = “”._\n\nLike modern languages, you don’t need to write the type of a variable when the compiler can infer the type, which can be done most of the times.\n\nAssignments can contain a conditional expresions, Kotlin has mutable and inmutable references, I usually feel safer when a variable is inmutable, sometimes, the value of a variable depends on some condition, and this could force you to make the variable mutable. I think this is better explained by this piece of code.\n\n```java\n// Java\n\nString greeting = null;\nif (isDaytime()) {\n greeting = “Good Morning”;\n} else {\n greeting = “good Evening”;\n}\n```\n\nKotlin allows you to write it in this way:\n\n```kotlin\nval greeting = if (isDaytime()) {\n “Good Morning”\n} else {\n “Good Evening”\n}\n```\n\nUsing this code, greeting is inmutable and you don’t need to check if it is null when using this variable.\n\n#### Vibrant community\n\nOne of the important things when using a new technology is the how its users communicate themselves. Kotlin community is great, you only need to connect to its slack channels and you will be able to talk with the developers of the language. Moreover, an increasing number of projects are starting to be developed using Kotlin, so you can share your experiences with others and learn by talking with them.\n\n#### Conclusions\n\nI could be talking about the features of Kotlin which we used while developing the watch face for hours, things like the functional features of Kotlin, the pattern matching of “switch” clauses, the bugs that optional types and immutability has saved us time of debugging and so on. In our experience choosing of Kotlin has been a great decision, it made our code more readable and one of the most important outcomes, we enjoyed a lot while developing the application which at the end is all that matters, isn’t it? :).\n\n","author":"Roberto Perez","date":"2016-03-28","type":"article","categories":["Android","Android Wear","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"A Whirlwind Tour of the Kotlin Type Hierarchy","url":"http://natpryce.com/articles/000818.html","body":"\nKotlin has plenty of good [language documentation](https://kotlinlang.org/docs/reference/) and [tutorials](https://kotlinlang.org/docs/tutorials/). But I’ve not found an article that describes in one place how Kotlin’s type hierarchy fits together. That’s a shame, because I find it to be really neat[1](#fn1).\n\nKotlin’s type hierarchy has very few rules to learn. Those rules combine together consistently and predictably. Thanks to those rules, Kotlin can provide useful, user extensible language features – null safety, polymorphism, and unreachable code analysis – without resorting to special cases and ad-hoc checks in the compiler and IDE.\n\n## Starting from the Top\n\nAll types of Kotlin object are organised into a hierarchy of subtype/supertype relationships.\n\nAt the “top” of that hierarchy is the abstract class `Any`. For example, the types String and Int are both subtypes of `Any`.\n\n![](http://natpryce.com/articles/000818/any-intrinsics.png)\n\n`Any` is the equivalent of Java’s `Object` class. Unlike Java, Kotlin does not draw a distinction between “primitive” types, that are intrinsic to the language, and user-defined types. They are all part of the same type hierarchy.\n\nIf you define a class that is not explicitly derived from another class, the class will be an immediate subtype of Any.\n\n class Fruit(val ripeness: Double)\n\n![](http://natpryce.com/articles/000818/any-user-defined-type.png)\n\nIf you do specify a base class for a user-defined class, the base class will be the immediate supertype of the new class, but the ultimate ancestor of the class will be the type Any.\n\n abstract class Fruit(val ripeness: Double)\n class Banana(ripeness: Double, val bendiness: Double): \n Fruit(ripeness)\n class Peach(ripeness: Double, val fuzziness: Double): \n Fruit(ripeness)\n\n![](http://natpryce.com/articles/000818/any-user-defined-type-hierarchy.png)\n\nIf your class implements one or more interfaces, it will have multiple immediate supertypes, with Any as the ultimate ancestor.\n\n```kotlin\ninterface ICanGoInASalad\ninterface ICanBeSunDried\n\nclass Tomato(ripeness: Double): \n Fruit(ripeness), \n ICanGoInASalad, \n ICanBeSunDried \n```\n\n![](http://natpryce.com/articles/000818/interfaces.png)\n\nThe Kotlin type checker enforces subtype/supertype relationships.\n\nFor example, you can store a subtype into a supertype variable:\n\n```kotlin\nvar f: Fruit = Banana(bendiness=0.5)\nf = Peach(fuzziness=0.8)\n```\n\nBut you cannot store a supertype value into a subtype variable:\n\n```kotlin\nval b = Banana(bendiness=0.5)\nval f: Fruit = b\nval b2: Banana = f\n// Error: Type mismatch: inferred type is Fruit but Banana was expected \n```\n\n## Nullable Types\n\nUnlike Java, Kotlin distinguishes between “non-null” and “nullable” types. The types we’ve seen so far are all “non-null”. Kotlin does not allow `null` to be used as a value of these types. You’re guaranteed that dereferencing a reference to a value of a “non-null” type will never throw a NullPointerException.\n\nThe type checker rejects code that tries to use null or a nullable type where a non-null type is expected.\n\nFor example:\n\n```kotlin\nvar s : String = null\n// Error: Null can not be a value of a non-null type String\n```\n\nIf you want a value to maybe be null, you need to use the nullable equivalent of the value type, denoted by the suffix ‘?’. For example, the type `String?` is the nullable equivalent `String`, and so allows all String values plus null.\n\n```kotlin\nvar s : String? = null\ns = \"foo\"\ns = null\ns = bar\n```\n\nThe type checker ensures that you never use a nullable value without having first tested that it is not null. Kotlin provides operators to make working with nullable types more convenient. See the [Null Safety section of the Kotlin language reference](https://kotlinlang.org/docs/reference/null-safety.html) for examples.\n\nWhen non-null types are related by subtyping, their nullable equivalents are also related in the same way. For example, because `String` is a subtype of `Any`, `String?` is a subtype of `Any?`, and because `Banana` is a subtype of `Fruit`, `Banana?` is a subtype of `Fruit?`.\n\nJust as `Any` is the root of the non-null type hierarchy, `Any?` is the root of the nullable type hierarchy. Because `Any?` is the supertype of `Any`, `Any?` is the very top of Kotlin’s type hierarchy.\n\n![](http://natpryce.com/articles/000818/parallel-nullable-and-non-nullable-hierarchies.png)\n\nA non-null type is a subtype of its nullable equivalent. For example, `String`, as well as being a subtype of `Any`, is also a subtype of `String?`.\n\n![](http://natpryce.com/articles/000818/nullable-string.png)\n\nThis is why you can store a non-null String value into a nullable String? variable, but you cannot store a nullable String? value into a non-null String variable. Kotlin’s null safety is not enforced by special rules, but is an outcome of the same subtype/supertype rules that apply between non-null types.\n\nThis applies to user-defined type hierarchies as well.\n\n![](http://natpryce.com/articles/000818/nullable-hierarchy.png)\n\n## Unit\n\nKotlin is an expression oriented language. All control flow statements (apart from variable assignment, unusually) are expressions. Kotlin does not have void functions, like Java and C. Functions always return a value. Functions that don’t actually calculate anything – being called for their side effect, for example – return `Unit`, a type that has a single value, also called `Unit`.\n\nMost of the time you don’t need to explicitly specify Unit as a return type or return Unit from functions. If you write a function with a block body and do not specify the result type, the compiler will treat it as a Unit function. Otherwise the compiler will infer it.\n\n```kotlin\nfun example() {\n println(\"block body and no explicit return type, so returns Unit\")\n}\n\nval u: Unit = example()\n```\n\nThere’s nothing special about `Unit`. Like any other type, it’s a subtype of `Any`. It can be made nullable, so is a subtype of `Unit?`, which is a subtype of `Any?`.\n\n![](http://natpryce.com/articles/000818/nullable-unit.png)\n\nThe type `Unit?` is a strange little edge case, a result of the consistency of Kotlin’s type system. It has only two members: the `Unit` value and `null`. I’ve never found a need to use it explicitly, but the fact that there is no special case for “void” in the type system makes it much easier to treat all kinds of functions generically.\n\n## Nothing\n\nAt the very bottom of the Kotlin type hierarchy is the type `Nothing`.\n\n![](http://natpryce.com/articles/000818/nothing.png)\n\nAs its name suggests, Nothing is a type that has no instances. An expression of type Nothing does not return a value.\n\nNote the distinction between Unit and Nothing. An expression type Unit evaluates to the singleton value Unit. An expression of type Nothing never returns at all.\n\nThis means that any code following an expression of type Nothing is unreachable. The compiler and IDE will warn you about such unreachable code.\n\nWhat kinds of expression evaluate to Nothing? Control flow.[2](#fn2)\n\nFor example, the `throw` keyword interrupts the calculation of an expression and throws an exception out of the enclosing function. A throw is therefore an expression of type Nothing.\n\nBy having Nothing as a subtype of every other type, the type system allows any expression in the program to actually fail to calculate a value. This models real world eventualities, such as the JVM running out of memory while calculating an expression, or someone pulling out the computer’s power plug. It also means that we can throw exceptions from within any expression.\n\n```kotlin\nfun formatCell(value: Double): String =\n if (value.isNaN()) \n throw IllegalArgumentException(\"$value is not a number\")\n else \n value.toString()\n```\n\nIt may come as a surprise to learn that the `return` statement has the type Nothing. Return is a control flow statement that immediately returns a value from the enclosing function, interrupting the evaluation of any expression of which it is a part.\n\n```kotlin\nfun formatCellRounded(value: Double): String =\n val rounded: Long = if (value.isNaN()) return \"#ERROR\" else Math.round(rounded)\n rounded.toString()\n```\n\nA function that enters an infinite loop or kills the current process has a result type of Nothing. For example, the Kotlin standard library declares the `exitProcess` function as:\n\n```kotlin\nfun exitProcess(status: Int): Nothing\n```\n\nIf you write your own function that returns Nothing, the compiler will check for unreachable code after a call to your function just as it does with built-in control flow statements.\n\n```kotlin\ninline fun forever(action: ()->Unit): Nothing {\n while(true) action()\n}\n\nfun example() {\n forever {\n println(\"doing...\")\n }\n println(\"done\") // Warning: Unreachable code\n}\n```\n\nLike null safety, unreachable code analysis is not implemented by ad-hoc, special-case checks in the IDE and compiler, as it has to be in Java. It’s a function of the type system.\n\n## Nullable Nothing?\n\n`Nothing`, like any other type, can be made nullable, giving the type `Nothing?`. `Nothing?` can _only_ contain one value: `null`. In fact, `Nothing?` _is_ the type of `null`.\n\n`Nothing?` is the ultimate subtype of all nullable types, which lets the value `null` be used as a value of any nullable type.\n\n![](http://natpryce.com/articles/000818/nullable-nothing.png)\n\n## Conclusion\n\nWhen you consider it all at once, Kotlin’s entire type hierarchy can feel quite complicated.\n\n![](http://natpryce.com/articles/000818/entire-hierarchy.png)\n\nBut never fear!\n\nI hope this article has demonstrated that Kotlin has a simple and consistent type system. There are few rules to learn: a hierarchy of supertype/subtype relationships with `Any?` at the top and `Nothing` at the bottom, and subtype relationships between non-null and nullable types. That’s it. There are no special cases. Useful language features like null safety, object-oriented polymorphism, and unreachable code analysis all result from these simple, predictable rules. Thanks to this consistency, Kotlin’s type checker is a powerful tool that helps you write concise, correct programs.\n\n\n1. “Neat” meaning “done with or demonstrating skill or efficiency”, rather than the [Kevin Costner backstage at a Madonna show](https://www.youtube.com/watch?v=wvZhW47mGNE) sense of the word.\n\n2. Apart from loops, which are statements. Variable assignments are also statements.\n\n\n\n","author":"Nat Pryce","date":"2016-10-28","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The Reactive Scrabble benchmarks","url":"http://akarnokd.blogspot.com.by/2016/12/the-reactive-scrabble-benchmarks.html","body":"\n### Introduction\n\nIn the past year, I've been posting benchmark results under the mysterious Shakespeare Plays (Reactive) Scrabble name. In this blog post, I'll explain what this benchmark is, where does it come from, how it works, what the intent is and how to apply it to your favorite and not-yet-benchmarked library. \n\n### History\n\nThe benchmark was [designed and developed](https://github.com/JosePaumard/jdk8-stream-rx-comparison) by [Jose Paumard](https://twitter.com/JosePaumard) and results presented in his [2015 Devoxx talk](https://www.youtube.com/watch?v=fabN6HNZ2qY) (a bit long but worth watching). The benchmark measures how fast a certain data-processing library can find the most valuable word from a set of words taken from (one of) Shakespeare's work based on the rules and point schema of Scrabble. RxJava at the time was in its 1.0.x version and to my surprise, it performed poorly compared to Java 8 Streams: \n\n[![](https://4.bp.blogspot.com/-GfETGQdChZo/WGJLllf3ddI/AAAAAAAAHiA/4d0vZHnioPE-yeQu1RY8OaULmi-gfQvQACLcB/s640/jose_scrabble_results.png)](https://4.bp.blogspot.com/-GfETGQdChZo/WGJLllf3ddI/AAAAAAAAHiA/4d0vZHnioPE-yeQu1RY8OaULmi-gfQvQACLcB/s1600/jose_scrabble_results.png)\n\n[https://youtu.be/fabN6HNZ2qY?t=8369](https://youtu.be/fabN6HNZ2qY?t=8369)\n\nThe benchmark, utilizing JMH, is completely synchronous; no thread hopping happens yet RxJava performs 10x slower, or more likely, it has 10x more overhead in the associated set of operators. In addition, Jose also added a parallel-stream version which runs the main \"loop\" in parallel before joining for the final result. \n\nMore disappointingly, RxJava 2 developer preview the time was terrible as well (relatively, [measured](https://twitter.com/akarnokd/status/696291409209487360) on a weak CPU in February). \n\nTherefore, instead of blaming the benchmark or the author, I set out on a quest to understand the benchmark's expectations and improve RxJava 2's performance and if possible, port that back to RxJava 1. \n\n### The original Stream-benchmark\n\nPerhaps the most easy way to understand how the computation in the benchmark works, Let's see the original, non-parallel `Stream` version of it. Since going sequential or parallel requires only a `sequential()` or `parallel()` operator on a `Stream`, they both extend an abstract superclass containing the majority of the code and only get specialized for the operation mode in two additional classes. \n\n[ShakespearePlaysScrabbleWithStreamBeta.java](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithStreamsBeta.java) \n\nI added postfix \"Beta\" - meaning alternate version in this context - to distinguish between a version that has a slight difference in one of the computation steps. I'll explain why when I describe the original RxJava-benchmark down below. \n\nThe benchmark is built in a somewhat unconventional, perhaps over-functionalized manner and I had a bit of trouble putting the functionality back together in my head. It isn't that complicated though. \n\nThe inputs to the benchmark are hidden in a base class' fields `shakespeareWords` (`HashSet`), `scrabbleWords` (`HashSet`), `letterScore` (`int[]`) and `scrabbleAvailableLetters` (`int[]`). `shakespeareWords` contains all the words, lowercased, of Shakespeare's work. `scrabbleWords` contains the allowed words, lowercased, by Scrabble itself. `letterscore` contains the scores of the scores of letters through a-z and `scrabbleAvailableLetters` (seems to me) is there to limit the score if the particular letter appears multiple times in a word. \n\nThe benchmark, due to dependencies of one step on the other, is written in \"backwards\" order, starting with a function that finds the score of a letter. Given an English letter with code `96-121`, the function maps it to the `0-25` range and gets the score from the array. \n\n```java\nIntUnaryOperator scoreOfALetter = letter -> letterScores[letter - 'a'];\n```\n\nThe next function, given a histogram of letters in a word in the form of a `Map.Entry` (where the key is the letter and the value is the number of occurrence in the word), calculates a bounded score of that letter in the word.\n\n```java\nToIntFunction> letterScore =\n entry ->\n letterScores[entry.getKey() - 'a'] *\n Integer.min(\n entry.getValue().intValue(),\n scrabbleAvailableLetters[entry.getKey() - 'a']\n );\n```\n\nFor that, we need the actual histogram of words which is computed by the following function: \n\n```java\nFunction> histoOfLetters =\n word -> word.chars()\n .boxed()\n .collect(\n Collectors.groupingBy(\n Function.identity(),\n Collectors.counting()\n )\n );\n```\n\nThis is where a particular dataflow library comes into play. Given a word as Java `String`, split it into individual characters and count how many of each character is in that word. For example, \"jezebel\" will count `1-j`, `3-e`, `1-z`, `1-b` and `1-l`. In the Stream version, the `IntStream` of characters provided by `String` itself is converted into a boxed `Stream` and grouped into a `Map` by a counting standard collector with no key mapping. Note that the return type of the function is `Map` and not `Stream`. \n\nThe next function calculates the blank score of a character occurrence: \n\n```java\nToLongFunction> blank =\n entry ->\n Long.max(\n 0L,\n entry.getValue() -\n scrabbleAvailableLetters[entry.getKey() - 'a']\n );\n```\n\nGiven an entry from the histogram above, it gives bonus points if the particular letter occurs more than its score in the `scrabbleAvailableLetters` array. For example, if the letter '`d`' appears twice, the `scrabbleAvailableLetters` for it is 1 and this computes to 1. If the letter 'e' appears twice, the array entry for it is 12 and the function computes 0. \n\nThe next function combines the `histoOfLetters` with the `blank` function to compute the number of blanks in an entire word: \n\n```java\nFunction nBlanks =\n word -> histoOfLetters.apply(word)\n .entrySet().stream()\n .mapToLong(blank)\n .sum();\n```\n\nHere the histogram of the letters in the given word is computed and returned in a `Map`, then each entry of this `Map` is streamed, mapped into the blank letter value and then summed up into a final value. (Honestly, I'm not familiar with the rules of Scrabble and this last two functions seem to be extra convolution to have the computation work harder.) \nThe follow-up function takes the result of `nBlanks` and checks if a word can be written with 2 or less blanks: \n\n```java\nPredicate checkBlanks = word -> nBlanks.apply(word) <= 2;\n```\n\nThe next 2 functions pick the first 3 and last 3 letters of a word: \n\n```java\nFunction first3 = word -> word.chars().limit(3);\nFunction last3 = word -> word.chars().skip(Integer.max(0, word.length() - 4));\n```\n\nThese won't stay separated and are immediately combined back together: \n\n```java\nFunction toBeMaxed =\n word -> Stream.of(first3.apply(word), last3.apply(word))\n .flatMapToInt(Function.identity());\n```\n\nPractically, the first 3 and last 3 letters (with possibly overlap for shorter words) are concatenated back into a single IntStream via `flatMapToInt`, i.e., \"jezebel\" will stream letter-by-letter as \"jezbel\". \n\nGiven the merged character stream, we compute the maximum score of the letters: \n\n```java\nToIntFunction bonusForDoubleLetter =\n word -> toBeMaxed.apply(word)\n .map(scoreOfALetter)\n .max()\n .orElse(0);\n```\n\nNote that `IntStream.max()` returns `Optional`. \n\nWe then calculate the final score of a word: \n\n```java\nFunction score3 =\n word ->\n 2 * (score2.apply(word) + bonusForDoubleLetter.applyAsInt(word))\n + (word.length() == 7 ? 50 : 0);\n```\n\nThis involves a bonus 50 points for words with length 7 and twice the score of the base word and the double letter bonus. Note that both `score2` and `bonusForDoubleLetter` are evaluated once and multiplied by the literal two. \n\nNow we reach the actual \"loop\" for calculating the scores of each word in the Shakespeare word set: \n\n```java\nFunction, Map>> buildHistoOnScore =\n score -> shakespeareWords.stream()\n .filter(scrabbleWords::contains)\n .filter(checkBlanks)\n .collect(\n Collectors.groupingBy(\n score,\n () -> new TreeMap>(Comparator.reverseOrder()),\n Collectors.toList()\n )\n );\n```\n\nThis is an odd function because it takes another function, the score function as input, returns a `Map` keyed by a score and a list of words that have that score. The body takes the set of `shakespeareWords`, streams it (the parallel version has `parallelStream()`) here, filters out those that are in the allowed Scrabble words set, filters out those that have less than two blank score, then groups the \"remaining\" words based on their computed score into a reverse-ordered `TreeMap` with `Integer` key and `List` elements - all with the help of standard `Stream Collectors`. \n\nFinally, we are not interested in all words but only the top 3 scoring set of words: \n\n```java\nList>> finalList =\n buildHistoOnScore.apply(score3)\n .entrySet()\n .stream()\n .limit(3)\n .collect(Collectors.toList());\n```\n\nWe apply the `score3` function to the \"loop\" and put the top 3 entries into the final list. If all went well, we should get the following entries: \n\n```\n120 = jezebel, quickly\n118 = zephyrs\n116 = equinox\n```\n\n### The original RxJava benchmark\n\nGiven the fact that RxJava and Java Streams have quite similar APIs and equivalent operators, the original RxJava benchmark was written with an odd set of helper components and changes to the pattern of the functions above. \n\nThe first oddity is the introduction of a functional style of counting: `LongWrapper` \n\n```java\ninterface LongWrapper {\n long get();\n \n default LongWrapper incAndSet() {\n return () -> get() + 1;\n }\n}\n \nLongWrapper zero = () -> 0;\nLongWrapper one = zero.incAndSet();\n```\n\n(This over-functionalization is a recurring theme with Jose, see this year's [JavaOne video](https://www.youtube.com/watch?v=Y4XkWSAm2XU) for example.) \n\nThe second oddity that many return types that were scalar in the `Stream` version above were turned into `Observable`s - which adds unnecessary overhead and no operational benefit. So let's see how the original benchmark looks like with RxJava 1: \n\nFirst, the `letterScore` now returns a single element `Observable` with the score value: \n\n```java\nFunc1> scoreOfALetter\n letter -> Observable.just(letterScores[letter - 'a']);\n \nFunc1, Observable> letterScore =\n entry ->\n Observable.just(\n letterScores[entry.getKey() - 'a'] *\n Integer.min(\n (int)entry.getValue().get(),\n scrabbleAvailableLetters[entry.getKey() - 'a']\n )\n );\n```\n\nThis has cascading effects as depending functions now have to deal with an `Observable`. RxJava doesn't have the direct means to stream the characters of a `String` so a helper indirection was introduced by reusing `Stream`'s tools and turning that into an `Iterable` RxJava can understand: \n\n```java\nFunc1> toIntegerObservable =\n string -> Observable.from(\n IterableSpliterator.of(string.chars().boxed().spliterator()));\n```\n\nBuilding the histogram now uses the `LongWrapper` and RxJava's `collect()` operator to build the `Map` with it: \n\n```java\nFunc1>> histoOfLetters =\n word -> toIntegerObservable.call(word)\n .collect(\n () -> new HashMap<>(),\n (HashMap map, Integer value) -> {\n LongWrapper newValue = map.get(value) ;\n if (newValue == null) {\n newValue = () -> 0L ;\n }\n map.put(value, newValue.incAndSet()) ;\n }\n );\n```\n\nCalculating blanks also return `Observable` instead of a scalar value: \n\n\n```java\nFunc1, Observable> blank =\n entry ->\n Observable.just(\n Long.max(\n 0L,\n entry.getValue().get() -\n scrabbleAvailableLetters[entry.getKey() - 'a']\n )\n );\n \nFunc1> nBlanks =\n word -> histoOfLetters.call(word)\n .flatMap(map -> Observable.from(() -> map.entrySet().iterator()))\n .flatMap(blank)\n .reduce(Long::sum);\n \nFunc1> checkBlanks =\n word -> nBlanks.call(word)\n .flatMap(l -> Observable.just(l <= 2L));\n```\n\nNow calculating the scores: \n\n```java\nFunc1> score2 =\n word -> histoOfLetters.call(word)\n .flatMap(map -> Observable.from(() -> map.entrySet().iterator()))\n .flatMap(letterScore)\n .reduce(Integer::sum);\n \nFunc1> first3 =\n word -> Observable.from(\n IterableSpliterator.of(word.chars().boxed().limit(3).spliterator()));\n \n \nFunc1> last3 =\n word -> Observable.from(\n IterableSpliterator.of(word.chars().boxed().skip(3).spliterator()));\n \n \nFunc1> toBeMaxed =\n word -> Observable.just(first3.call(word), last3.call(word))\n .flatMap(observable -> observable);\n \nFunc1> bonusForDoubleLetter =\n word -> toBeMaxed.call(word)\n .flatMap(scoreOfALetter)\n .reduce(Integer::max);\n```\n\n(Note that `last3` returns the letters 4..n instead of the last 3 letters, not sure if this was intentional or not. Changing it to really return the last 3 letters has no measurable performance difference.) \n\nThen we compute the final score per word: \n\n```java\nFunc1> score3 =\n word ->\n Observable.just(\n score2.call(word),\n score2.call(word),\n bonusForDoubleLetter.call(word),\n bonusForDoubleLetter.call(word),\n Observable.just(word.length() == 7 ? 50 : 0)\n )\n .flatMap(observable -> observable)\n .reduce(Integer::sum);\n```\n\nRemember the \"times 2\" from the `Stream` benchmark, here both scores are streamed again instead of multiplying their result by 2 (via map). This inconsistency with the original `Stream` alone is responsible of ~30% overhead with the original RxJava 1 benchmark. For comparison, when the same double-streaming is applied to the original Stream benchmark, its measured sample time goes from **27 ms/op** up to **39 ms/op**. \n\nLastly, the processing of the entire Shakespeare word set and picking the top 3: \n\n```java\nFunc1>, Observable>>>\nbuildHistoOnScore =\n score -> Observable.from(() -> shakespeareWords.iterator())\n .filter(scrabbleWords::contains)\n .filter(word -> checkBlanks.call(word).toBlocking().first())\n .collect(\n () -> new TreeMap>(Comparator.reverseOrder()),\n (TreeMap> map, String word) -> {\n Integer key = score.call(word).toBlocking().first();\n List list = map.get(key);\n if (list == null) {\n list = new ArrayList<>();\n map.put(key, list);\n }\n list.add(word);\n }\n );\n \nList>> finalList2 =\n buildHistoOnScore.call(score3)\n .flatMap(map -> Observable.from(() -> map.entrySet().iterator()))\n .take(3)\n .collect(\n () -> new ArrayList>>(),\n (list, entry) -> {\n list.add(entry);\n }\n )\n .toBlocking()\n .first();\n```\n\nHere, we need to go blocking to get the first (and) only value for the `checkBlanks` as well as getting the only List of results of the final list of top 3 scores and words. The collector function taking the `TreeMap` and the current entry had to be explicitly typed because for some reason Eclipse can't properly infer the types in that expression. \n\n### The optimized version\n\nThe mistakes and drawbacks of the original RxJava version has been identified over a long period of time and the optimized benchmark is still \"under optimization\". Using the right operator for the right job is essential in synchronous processing and some are better suited for this type of work and have less overhead due to their need to support an asynchronous operation mode. The other important thing is to know when to use a reactive type and when to stick to a scalar value. \n\nAs mentioned above, the original RxJava benchmark had a bunch of the functions return `Observable` with a scalar value for no apparent benefit. Changing these back to scalar functions - just like the Stream version helps avoid unnecessary indirection and allocation: \n\n```java\nFunc1 scoreOfALetter = letter -> letterScores[letter - 'a'];\n```\n\nStreaming the characters of a word is the hottest operation and is executed several tens of thousands of time. Instead of the `Stream-Spliterator` indirection, one can simply index-map a string into its characters: \n\n```java\nword -> Observable.range(0, word.length()).map(i -> (int)word.charAt(i));\n```\n\nInstead of the convoluted `LongWrapper` and its lambda-capture overhead, we can define a simple mutable container for the histogram: \n\n```java\npublic final class MutableLong {\n \n public long value;\n \n public void incAndSet() {\n value++;\n }\n}\n \nFunc1>> histoOfLetters =\n word -> toIntegerObservable.call(word)\n .collect(\n () -> new HashMap<>(),\n (HashMap map, Integer value) -> {\n MutableLong newValue = map.get(value);\n if (newValue == null) {\n newValue = new MutableLong();\n map.put(value, newValue);\n }\n newValue.incAndSet();\n }\n \n );\n```\n\nThe next optimization is the use of `flatMapIterable` and there is no need to get the iterator of an `entySet()` but just iterate it since it already implements `Iterable`: \n\n```java\nFunc1> nBlanks =\n word -> MathObservable.sumLong(\n histoOfLetters.call(word)\n .flatMapIterable(map -> map.entrySet())\n .map(blank)\n );\n```\n\nIn addition, `reduce()` has some overhead because of constant boxing and unboxing of a sum or max value of the stream and can be replaced by a dedicated operator from the [RxJavaMath](https://github.com/ReactiveX/RxJavaMath) library: `MathObservable.sumLong()`. \n\nIn synchronous scenarios, `concat` works better than `merge/flatMap` most of the time: \n\n```kotlin\nFunc1> toBeMaxed =\n word -> Observable.concat(first3.call(word), last3.call(word));\n \nFunc1> score3 =\n word ->\n MathObservable.sumInteger(\n Observable.concat(\n score2.call(word).map(v -> v * 2),\n bonusForDoubleLetter.call(word).map(v -> v * 2),\n Observable.just(word.length() == 7 ? 50 : 0)\n )\n );\n```\n\nNote the use of `map(v -> v * 2)` to multiply the two score components instead of streaming them again. \n\nIn addition, there were several internal optimizations to RxJava to improve performance with this type of usage: `concat(o1, o2, ...)` received a dedicated operator instead of delegating to the `Observable` of `Observable`s overload. The `toBlocking().first()` overhead has been improved as well. Currently, the optimized benchmark with RxJava 1.2.4 runs under **67 ms/op**, the \"Beta\" benchmark runs under **100 ms/op** and the original benchmark runs under **170 ms/op**. \n\n### Benchmarking other libraries\n\nFollowing similar patterns, other streaming libraries (synchronous and asynchronous) were benchmarked over the year. The following subsections summarize what it takes to have them do the Scrabble computation with the functional structures above, how they perform and why are they at the speed they are. \n\n[![](https://4.bp.blogspot.com/-V_cLB3fnjQM/WGJ4q3uAqBI/AAAAAAAAHiQ/TpuXI4nHu0gvPBXsrvKGk0y4w4C8Hn6vACLcB/s640/Scrabble_12_14.jpg)](https://4.bp.blogspot.com/-V_cLB3fnjQM/WGJ4q3uAqBI/AAAAAAAAHiQ/TpuXI4nHu0gvPBXsrvKGk0y4w4C8Hn6vACLcB/s1600/Scrabble_12_14.jpg)\n\n[https://twitter.com/akarnokd/status/808995627237601280](https://twitter.com/akarnokd/status/808995627237601280)\n\n#### Kotlin\n\nKotlin has its own, rich synchronous streaming standard library and performs quite well in the optimized benchmark: **20 ms/op**. It requires a [separate project](https://github.com/akarnokd/akarnokd-misc-kotlin/blob/master/src/main/kotlin/hu/akarnokd/kotlin/scrabble/ScrabbleKotlin.kt#L195) due to a complete separate JVM language which works best under IntelliJ. I'm not deeply familiar with Kotlin thus I'm not sure what it makes that much faster than `Stream` (or IxJava). \n\nThe streaming part of the language is certainly well optimized but it is also possible using `HashMap` with primitive types gets custom implementation. The streaming standard library is very rich and the whole Scrabble logic could be expressed without building new operators or invoking external libraries. \n\n#### IxJava\n\nIxJava, short for _Iterable eXtensions_ for Java started out as a companion library to Reactive4Java, the first black-box re-implementation of the Rx.NET library on the JVM (2011). Since then, it has been rewritten from scratch based on the advanced ideas of RxJava 2. The [optimized benchmark](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithIxOpt.java) runs around **23 ms/op**, 3 ms faster than the `Stream` version. Currently, this is the fastest Java library to do the Scrabble benchmark and has all the operators built in for the task. It features less allocation and less indirection, plus there are optimizations for certain shapes of inputs (constant-scalar, single-element sources). \n\n#### RxJava 2\n\nRxJava is the de-facto standard reactive library for Java 6+ and version 2 supports the Reactive-Streams initiative with its `Flowable` type. Version 2 was rewritten from scratch in late 2015 and then has been drastically re-architected in mid 2016. The late 2015 version performed poorly with the scrabble benchmark but still 2 times faster than RxJava 1 at the time. Since the dataflow types in RxJava have to anticipate asynchronous and/or backpressured usage with largely the same code path, they have a noticeable overhead when using them in a pure synchronous manner. \n\nTherefore, the Scrabble benchmark is implemented for the [backpressure-enabled Flowable](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithRxJava2FlowableOpt.java) and the [backpressure-lacking (but otherwise similarly advanced) Observable](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithRxJava2ObservableOpt.java) types. They perform **27.75 ms/op** and **26.83 ms/op** respectively. Unfortunately, the main RxJava library lacks dedicated operators such as streaming the characters of a `String` and summing up a stream of numbers and these were implemented in the [RxJava 2 Extensions](https://github.com/akarnokd/RxJava2Extensions) companion library. The additional performance improvement over RxJava 1.x come from the much leaner architecture with fewer indirections, fewer allocations, dedicated `concat(source1, source2, ...)` operator, a very low overhead `blockingFirst()` and generally the operator fusion many operators participate in. In the late release-candidate phase, it was decided certain operators return `Single`, `Completable` or `Maybe` instead of its own type. The change did not affect the benchmark result in any measurable way (but the code had to change to work with the new types of course). \n\nIn addition, the extension library features a `ParallelFlowable` type that allows parallel computations over a regular `Flowable` sequence, somewhat similar to parallel Streams. The parallelization happens for the set of Shakespeare words and requires a manual reduction back to sequential reactive type: \n\n```kotlin\nFunction>, Flowable>>>\nbuildHistoOnScore =\n score ->\n ParallelFlowable.from(Flowable.fromIterable(shakespeareWords))\n .runOn(scheduler)\n .filter(scrabbleWords::contains)\n .filter(word -> checkBlanks.apply(word).blockingFirst())\n .collect(\n () -> new TreeMap>(Comparator.reverseOrder()),\n (TreeMap> map, String word) -> {\n Integer key = score.apply(word).blockingFirst();\n List list = map.get(key);\n if (list == null) {\n list = new ArrayList<>();\n map.put(key, list);\n }\n list.add(word);\n }\n )\n .reduce((m1, m2) -> {\n for (Map.Entry> e : m2.entrySet()) {\n List list = m1.get(e.getKey());\n if (list == null) {\n m1.put(e.getKey(), e.getValue());\n } else {\n list.addAll(e.getValue());\n }\n }\n return m1;\n });\n```\n\nThe parallel version measures **7.23 ms/op** compared to the Java parallel Streams version with **6.71 ms/op**. \n\n#### Reactor 3\n\nPivotal's Reactor-Core library is practically RxJava 2 under a different company banner and implementation differences due to being Java 8+, originally contributed by me and as of today, the relevant components of Reactor 3 required by the Scrabble benchmark still uses my algorithms. The few implementation differences come from the use of atomic field updaters instead of atomic classes (such as AtomicInteger) which reduces the allocation amount even further. Unfortunately, even though the same field updaters are available for Java 6 and Android, certain devices don't play nicely with the underlying reflection mechanics. The [optimized benchmark code](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithReactor3Opt.java) uses custom implementation for streaming the characters of a word and finding the sum/max of a sequence. \n\nGiven this difference, Reactor measures **27.39 ms/op**, putting it between RxJava 2's `Observable` and `Flowable`, somewhat expectedly. \n\nReactor 3 has direct support for converting to its parallel type, `ParallelFlux`, which is also practically the same as RxJava 2 Extensions' `ParallelFlowable`. The [ParallelFlux' benchmark](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithReactor3ParallelOpt.java) clocks in at **8,53 ms/op**, however, that 1 ms difference to RxJava 2 is certainly odd and unclear why. \n\n#### Guava\n\nGoogle Guava is library with lots of features, among other things, offering sub-library with a fluent-API support with `FluentIterable`. It has a limited set of streaming operators and the implementation has some unccessary overhead in it. The design reminds me of RxJava 1's Observable where there is a mandatory indirection to an inner type. \n\nGiven the limited API, the [optimized benchmark code](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithGuavaOpt.java) uses custom operators such as streaming the characters of a word, custom `sum`/`max` and custom `collect()` operators, all written with the vocabulary of `FluentIterable` by me. Therefore, the measured `35.98 ms/op` is not entirely the achievement of the library authors. \n\nInterestingly, the backpressure-enabled, async capable `Flowable`/`Flux` outperforms the sync-only and thus theoretically lower overhead `FluentIterable`. \n\n#### Ix.NET\n\nWhen the Rx.NET was developed several years ago, they implemented its dual, the Interactive eXtensions building a rich API over their standard, synchronous streaming IEnumerable interface. \n\nIx.NET is well optimized, most likely due to the nice language features (`yield return`) and great compiler (state machine building around `yield return`). Even though .NET supports \"primitive specialization\", their JIT compiler is not a runtime optimizing compiler and this is likely why the ported [Scrabble benchmark measures](https://github.com/akarnokd/akarnokd-misc-dotnet/blob/master/akarnokd-misc-dotnet/ShakespearePlaysScrabbleIxNET.cs) only **45.4 ms/op**. \n\nUnfortunately, there were some missing operators from Ix.NET I had to write manually, such as the now-typically needed streaming of characters and the `reduce()` operator to support sum/max. (There is no need for custom sum because of the primitive specialization of `reduce()` provided automatically.) \n\n#### Reactor.NET\n\nAbout a year ago, there was a non-zero chance I had to learn and include C# development in my professional line of work. Unfortunately, Rx.NET was and still is an old library with a significant performance overhead due to its synchronous ties, namely returning an `IDisposable` from `Subscribe()` instead of injecting it via an `OnSubscribe()` like all the other 3rd generation (inspired) libraries do. When 3.x didn't change the architecture, I decided instead of battling them over advancing, I could just roll my own library. Since in early 2016 I was involved with Pivotal's Reactor and its third-the-size API surface, I started working on [Reactor-Core.NET](https://github.com/reactor/reactor-core-dotnet) with all the 4th generation goodies RxJava 2 and Reactor now feature. Unfortunately, the risk of me doing C# faded and I took over leading RxJava, sending this project into sleep. \n\nRegardless, enough operators were implemented already so the [Scrabble benchmark for it](https://github.com/akarnokd/akarnokd-misc-dotnet/blob/master/akarnokd-misc-dotnet/ShakespearePlaysScrabbleReactorCore.cs) is available and measures **80.51 ms/op**. It may be party due to the .NET platform and also due to a less-than-optimal implementation for streaming characters. \n\n#### JOOLambda\n\nBack to the Java land, [this library](https://github.com/jOOQ/jOOL) is part of the JOOx family of extension libraries, supporting JVM operations such as JDBC-based database interactions to extending the standard Java Stream with features. This, unfortunately, means wrapping a `Stream` or their `Seq` type and thus adding a level of indirection. This wouldn't be much of a problem but the API lacks operators that stay in the Seq type for tasks such as collect or sum/max. Therefore, these operators had to be emulated with other operators. A second unfortunate property of JOOLambda is the difficulty of extending it (even non-fluently). I could't find any way of implementing my own operator directly (as with the Rx style and Ix-style APIs) and the closest thing wanted me to implement 70+ standard `Stream` operators again. \n\nI believe it is still interesting to show how a convenient `collect()` operator can be implemented if there is no `reduce()` or even `scan()` to help us: \n\n```java\nFunction>> histoOfLetters =\n word -> {\n HashMap map = new HashMap<>();\n return charSeq.apply(word)\n .map(value -> {\n MutableLong newValue = map.get(value);\n if (newValue == null) {\n newValue = new MutableLong();\n map.put(value, newValue);\n }\n newValue.incAndSet();\n return map;\n })\n .skip(Long.MAX_VALUE)\n .append(map);\n };\n```\n\nFirst, the resulting `HashMap` is instantiated, knowing that this function will be invoked sequentially, non-recursively thus there won't be any clash between computations of different words. Second, we stream the characters of the word, map each character into the histogram inside the map. We need only a single element of the `HashMap` but there is no `takeLast()` operator to ignore all but the very last time the map is forwarded. Instead, we skip all elements and concatenate the single `HashMap` again to the now empty `Seq`. \n\nSumming up values is none the less convoluted with JOOL: \n\n```kotlin\nFunction> score2 =\n word -> {\n int[] sum = { 0 };\n return histoOfLetters.apply(word)\n .flatMap(map -> Seq.seq(map.entrySet()))\n .map(letterScore)\n .map(v -> sum[0] += v)\n .skip(Long.MAX_VALUE)\n .append(0)\n .map(v -> sum[0]);\n };\n```\n\nWe setup a single element array to be the accumulator for the summing, stream the histogram and sum up the letter scores into this array. We then skip all of it and concatenate 0 followed by mapping (this zero) to the contents of the sum array. Note that `append(sum[0])` is evaluated at assembly time (before the sum actually happens) yielding the initial zero every time. \n\nThe code measures **86-92 ms/op**, however, this might not be that bad because when I'm writing this post, I've noticed a [missing optimization](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithJOOLOpt.java#L54) that adds unnecessary burden to a core computation - my bad. No worries, I'll remeasure everything again next year since some libraries have since updated their code. \n\n#### Cyclops-React\n\n[This is an odd library](https://github.com/aol/cyclops-react), developed mainly by one person. Looking at the Github site I'm sure it used to say Reactive-Streams in the title. I've come across this library a month or so back when the author posted an extensive post about the benefits of it by extending Java Stream with [missing features and reactive concepts](https://medium.com/@johnmcclean/java-8-streams-10-missing-features-ec82ee90b6c0#.j17ift5f9). When I see \"library\" and \"Reactive-Streams\" I jump - writing a reactive library is a very difficult task. It turns out, the library's call in of \"Reactive-Streams\" was a bit misleading. It is no more reactive than IxJava, which is a completely synchronous streaming API, with the exception that there is a wrapper/converter to a Reactive-Streams Publisher. IxJava has that one but only in various other reactive libraries: `Flux.fromIterable()` and `Flowable.fromIterable()`. \n\nThat aside, it is still a kind of dataflow library and as such can be benchmarked with Scrabble. Cyclops-React builds on top of JOOLambda and my first [naive implementation](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithCyclopsReactOpt.java) performed similarly to JOOLambda (to be precise, I measured Cyclops-React first, then JOOLambda to see where the poor performance might come from). \n\nCyclops-React at the time didn't have any `collect()`/`reduce()` operators but it has `scan` (called `scanLeft`) and `takeLast` (called `takeRight`), allowing me to build the necessary computation steps: \n\n```kotlin\nFunction>> histoOfLetters =\n word -> toIntegerIx.apply(word)\n .scanLeft(new HashMap(), (map, value) -> {\n MutableLong newValue = map.get(value) ;\n if (newValue == null) {\n newValue = new MutableLong();\n map.put(value, newValue);\n }\n newValue.incAndSet();\n return map;\n })\n .takeRight(1);\n```\n\nFrom allocation perspective, this is very similar to JOOLambda's workaround since the `HashMap` is instantiated when the outer function is called and not for the consumer of the aggregation like with RxJava's `collect()` operator. One convenience though is the `takeRight(1)` that picks the very last value of the map (as `scan` emits it every time a new source comes up). \n\nThe first benchmarks with version 1.0.3 yielded **108 ms/op**. The diagram at the beginning of this section lists it twice. The author of Cyclops-React and I tried to work out a better optimization, but due to the different understanding what the Scrabble benchmark represents, we didn't come to an agreement on the proper optimization (he practically wanted to remove `ReactiveSeq`, the base type of the library, and basically benchmark Java Stream again; I want to measure the overhead of ReactiveSeq itself). \n\nSince then, version 1.0.5 has been released with library optimizations and my code runs under **54 ms/op** while having the same structure as before. The author has also run a few Scrabble benchmarks of his own [that show lower overhead](https://twitter.com/cyclops_aol/status/809544009236496384), comparable to `Stream` now. If he achieved it by honoring the structure, that's fantastic. If he practically skipped his own type as the workhorse, that's bad. \n\n#### Rx.NET\n\nThe first, modern reactive library was designed and developed more than 8 years ago at Microsoft. Since then, Rx.NET has become open source, had 3 major releases, and helps (drives?) famous technologies such as Cortana. \n\nIt's a bit sad it couldn't evolve beyond its 1st generation reactive architecture. First, it has heavily invested developers who are quite comfortable with how it is implemented, second, the .NET platform has absorbed its base interface types, `IObservable` and `IObserver`, that have the unfortunate design of requiring a synchronous `IDisposable` to be returned. Luckily, the 4th generation architecture works on the .NET platform and the community driven [Reactive-Streams.NET](https://github.com/reactive-streams/reactive-streams-dotnet) initiative may give some hope there as well. \n\nThis unfortunate design remnant is visible in the [Scrabble benchmark](https://github.com/akarnokd/akarnokd-misc-dotnet/blob/master/akarnokd-misc-dotnet/ShakespearePlaysScrabbleRxNET.cs): **413 ms/op**. The main overhead comes from the trampolining the `range()` and enumerable-to-Observable conversion have. This trampolining is necessary to solve the synchronous cancellation problem RxJava solved by having a stateful consumer with a flag and callback mechanism indicating cancellation (which lead to the Subscription injection method in Reactive-Streams). \n\nInterestingly, I've [implemented](https://github.com/akarnokd/akarnokd-misc-dotnet/tree/master/akarnokd-misc-dotnet/observablex) a minimalist, non-backpressured type `Ox`, similar to RxJava 2's Observable type and [it measures](https://github.com/akarnokd/akarnokd-misc-dotnet/blob/master/akarnokd-misc-dotnet/ShakespearePlaysScrabbleOx.cs) **45 ms/op**, practically in par with the Ix.NET benchmark. \n\n#### Swave\n\nPerhaps [this library](https://github.com/sirthias/swave/) is the youngest of the \"reactive\" libraries. It's implementation resembles of Akka-Stream with the graph-like internal workings, but it is not a native Reactive-Streams library. It has conversion from and to Publisher but steps themselves aren't Publishers. This adds interoperation overhead. In addition, the library is part of the _Yoda-family_ of reactive libraries; there is no `retry`. (Maybe because for retry to work, one needs to hold onto the chain that establishes the flow and allow resubscribing without the need for manual reassembing the entire flow.) The library is written in Scala entirely and I gave up on trying to call it from a Java project, hence a separate project for it. \n\nThe library itself appears to be single developer only and the documentation is lacking a bit at the moment - not that I can't find operators on my own but a few times it was unclear I'm fighting with the Scala compiler (through IntelliJ) or with this library (you know, when IntelliJ says all is okay but then the build fails with a compilation error due to implicits). The library, version 0.5 at least, didn't have `collect`, `reduce`, `sum`, `max` but it does have `takeLast` and the emulations mentioned before work. \n\nNone the less, I managed [to port the benchmark](https://github.com/akarnokd/akarnokd-misc-scala/blob/master/src/main/scala/ScrabbleWithSwave.scala) to Scala and run it, getting a surprising **781 ms/op**. Since I can't read Scala code, I can only speculate this comes from the graph-architecture overhead and/or some mandatory asynchronous-ness implicitly present. \n\n#### Akka-Stream\n\nI've read so much goodness about Akka-Stream, about the technologies and frameworks it supports, its advanced and high performance optimizations over the flow-graph, the vibrant community and developer base around it, the spearheading of the Reactive-Streams initiative itself yet it constantly fails to deliver for me. In addition I've recently found out Akka-Stream is just inspired by Reactive-Streams and the reason they provide converter/wrapper to a Publisher instead of implementing it at every step is because working Reactive-Streams' deferred nature is too hard. Also I couldn't find any means for retrying an Akka-Stream `Source` so it could be yet another Yoda-library (so how does it support resilience then?). \n\nAt least Akka-Stream has a Java DSL so I could implement the [Scrabble benchmark](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/scrabble/ShakespearePlaysScrabbleWithAkkaStreamOpt.java) within the familiar Java context. The DSL doesn't have `collect` but supports `reduce` (thus sum and max requires minimal work). Therefore, the collect operations were implemented with the same `map+drop(Long.MAX_VALUE)+concat(map)`. \n\nThe benchmark results are \"mind-blasting\": **5563 ms/op**, that is, it takes about 5.5 seconds to compute the Scrabble answer once. Since Akka-Stream is originally written in Scala, I don't know for sure the source of this overhead but I have a few ideas: the graph-overhead, the mandatory asynchronous nature and perhaps the \"fusion optimization\" they employ that wastes time [trying to optimize](https://github.com/akka/akka/issues/20218) a graph that can't be further optimized. \n\nThis problem seem to hit any use case that has `flatMap` in it - one of the most common operator involved in Microservices composition. Of course, one can blame the synchronous nature Scrabble use case which is not the target for Akka-Stream, however, its interoperation capabilities through Reactive-Streams Publisher shows some serious trouble (ops/s, larger is better): \n\n[![](https://2.bp.blogspot.com/-Ln91ysLDeC0/WGKwuJHW3kI/AAAAAAAAHiw/MU3rVRtMqmgZowQyRnuKmOJExEfdpBFawCLcB/s640/akka-rx-crossperf.png)](https://2.bp.blogspot.com/-Ln91ysLDeC0/WGKwuJHW3kI/AAAAAAAAHiw/MU3rVRtMqmgZowQyRnuKmOJExEfdpBFawCLcB/s1600/akka-rx-crossperf.png)\n\nHere, [the task is to deliver](https://github.com/akarnokd/akarnokd-misc/blob/master/src/jmh/java/hu/akarnokd/comparison/AkkaStreamsCrossMapPerf.java) 1M elements (part of an Integer array) from one thread to another where the work is divided between Akka-Stream and RxJava 2: one delivers `count` number of `1M/count` items, and the other flattens the latter sub-section back to a single stream at the other side. Surprisingly, using Rx as the driver or middle worker improves throughput significantly (but not always). This benchmark stresses mostly the optimizer of Akka-Stream. Do people `flatMap` with Akka-Stream at all and nobody noticed this? \n\n### Conclusion\n\nWriting a reactive library is hard, writing a benchmark to measure those libraries is at best non-trivial. Figuring out why some of them is extremely fast while others are extremely slow requires mastery in both synchronous and asynchronous design and development. \n\nInstead of getting mad at the Scrabble benchmark a year ago, I invested time and effort into improving and optimizing libraries that I could effect and thanks to it, those libraries are now considerably better at this benchmark and in general use due to the deep architectural and conceptional improvements. \n\nI must warn the reader about interpreting the results of the Scrabble benchmarks as the ultimate ranking of the libraries. The fact that libraries perform as they do in this particular benchmark doesn't mean they perform the same in any other situations with other type of tasks. The computation and/or IO overhead may hide the subtle differences in those cases, evening the field between them at the end. \n\n","author":"Dávid Karnok","date":"2016-12-27","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin: How to Make a Java Developer's Life Easier?","url":"https://anadea.info/blog/kotlin-how-to-make-java-developers-life-easier","body":"\n![Kotlin](https://anadea.info/uploads/image_attachment/image/1025/xKotlin.jpg.pagespeed.ic.Wy-yOp4EYc.jpg)\n\nOn February 15, 2016 JetBrains company released version 1.0 of [Kotlin](https://kotlinlang.org/), a programming language that has been in development for about 5 years. This language works on JVM. We've already talked about [what Java is](https://anadea.info/blog/java-myths-realities-and-prospects-for-application-development) with our developer Alexander Mihalchenko. Today, we met again with Alexander, this time to discuss Kotlin - why Kotlin is good and if there are any drawbacks of using this language, both for developers and for entrepreneurs.\n\n**Hello, Alex.** \nHi to you too.\n\n**So, what is Kotlin?** \nKotlin is a programming language, developed by JetBrains company, running on the Java platform. It uses JDK, like Java itself but has a different syntax. The idea isn't new, there are already existing languages that do the same - Scala and Closure, for example. They appeared mainly because of issues with Java in terms of syntax. In other words, Java is a good, reliable and powerful language, you can use it to build server-side applications. However, its syntax, let's say, is unnecessarily wordy. The fact is that Java's developers upgrade it in a rather inertly manner. They are keeping maximal backward compatibility and consider that, when uses move to a new version of Java, a code written back in '95 should work for them anyway. They even have a slogan: \"write once, run anywhere\". Of course, this is more about cross-platform benefits of Java...\n\n**... but they decided to dig deeper?** \nYes, the code written on one version of Java will work on all following versions.\n\n**A bold aspiration!** \nIn fact, this is where the problem lies - they do not throw old things from the language. This slows down the development of Java. Over time, various trash comes up. There's even a label for outdated classes, which marks them inside the JDK. According to documentation, when such label appears it means that the old functionality may be ceased in the next versions, but I'm not aware of any occasions when it actually happened.\n\n**Do developers recognize that these outdated methods aren't used anymore?** \nThey understand and even insist that these methods should not be used. But as far as there is a software apps written on old versions, it's not possible to simply remove the old code. All those applications will get broken.\n\n**So, what did Kotlin get rid of?** \nKotlin and other JVM-languages help developers to write programs with less code. In addition to everything that exists in Java, they provide things from the world of functional programming. This greatly facilitates code writing, makes it more concise and expressive. The less code we write, the less of it needs to be maintained and the fewer tests we have to write. Actually, the majority of programming languages emerged because of this particular reason - to change Java syntax, make it more convenient and more pragmatic.\n\n**Is the Kotlin language in a high demand now?** \nCurrently, it is not very popular - the language is young, its community hasn't come together yet. Due to immaturity of Kotlin vs Scala they can't compete so far. Scala is a more powerful programming language with a long history. Scala has already passed the stage of fixing major errors and it has been updated to include a bunch of interesting stuff, while this have yet to be done for Kotlin. More mature languages have the upper hand in that for now. Nevertheless, Kotlin has a lot of ambitions. The language has been in development for five years. Developers tried to make it pragmatic and avoid mistakes that have been made in Java. So, that \"write once\" won’t be the major rule and the language will be easier to develop. In the future, they promise a lot of interesting features that will cover functionality currently available in Scala.\n\n**Is it true that, like Java, Kotlin will suit better to large-scale projects?** \nYes. By the syntax, it can be used just as an addition to Java. We can take the Java stack for server applications and simply replace Java with Kotlin. Everything will work and it'll be easier to write code. The question is what to choose instead of Java. Today, I think, the majority of developers will pick Scala.\n\n**What's your personal opinion? Do you prefer Kotlin or Scala?** \nI like both languages. I think Kotlin will go further in respect of Android. Surely it's possible to write Android apps on Scala but there is a problem - a large runtime. It pulls behind a heap of libraries and because of that the size of apk-files increases. Kotlin already has the smallest runtime among the other languages (except Java). Typically, it's Java plus \"something\" and that \"something\" is an overhead that is trailed behind the language. Kotlin has smallest one - about 700 KB, while in Scala it is a few megabytes.\n\n**What are the disadvantages of Kotlin?** \nI haven't yet come across any bugs myself and I had no problems with compiler or anything else as well. As for the syntax, it coped with all challenges I have encountered. The thing it yields to Scala is dealing with multithreading. Java, by the way, also loses in this. There is Future API in Scala. It allows you to perform asynchronous tasks in several streams. As a result, you get a normal code instead of hash of various sections operating in different streams without any visible relation between them. Scala structures all of it through the means of syntax. In Kotlin, something similar is promised to be implemented in version 1.1. But generally, I like to use Kotlin due to its solid syntax.\n\n**What can you say about safety of Kotlin?** \nHere's the thing: all the code written in Kotlin is then converted into a Java code. It adds nothing from itself. Accordingly, Kotlin is safe to the same extent as Java. If we are speaking about safety of writing code, I really like Null safety in Kotlin programming. The compiler can warn coder that the reference may be empty. If we try to do anything with it, an error occurs at the compiling stage. In Java, application simply crushes at the implementation stage.\n\n**What can Kotlin offer to business? What benefits does it provide to entrepreneurs?** \nFor business, the key benefit of Kotlin vs Java is the fact that the development on Kotlin is cheaper. Why? It requires to write less code and as a result you get fewer code to maintain. This means that it is easier to write code and consequently the application can be developed faster. Time is money, after all.\n\n**Small projects and Kotlin.** \nIf we are speaking about small desktop apps, for commercial use it is better to choose C++. Yet again, Kotlin code is subsequently compiled to Java bytecode, therefore, as far as Java is good in some area, so good Kotlin as well. Kotlin is more helpful for writing programs, so it brings direct benefits primarily to coders.\n\n**Thank you very much for the interview, Alex. It was interesting!** \nMy pleasure.\n\n## Summary\n\nIn fact, Kotlin's direct purpose is to facilitate life of coders, give them opportunity to use one code line where Java needs five lines. As Alexander said, it's like changing an old Ford Focus to a brand new BMW M3 - when you feel that flight you won't come back to the old wheels.\n\nOne of the undoubted advantages of Kotlin is the full compatibility with Java, including backwards one. All libraries for Java will work on Kotlin and vice versa. Also, this language reveals the charms of Closure and Scala for Android developers. Entrepreneurs will be pleased as well as now software projects will be delivered faster and cheaper.\n\nThe only drawback of the language is its young age. However, considering the fact that JetBrains spent five years on its development, they will unlikely abandon their brainchild any time soon. Therefore, it is a good idea to start adopting Kotlin right now, especially if you're developing apps for Android.\n\n","author":"Stanislav Sinitsky, Alexander Mikhalchenko","date":"2016-12-07","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1 Beta 2 is here","url":"https://blog.jetbrains.com/kotlin/2017/02/kotlin-1-1-beta-2-is-here/","body":"\nWe’re happy to announce the second beta of Kotlin 1.1. Please give the new version a try – your feedback is essential for ensuring that we can deliver a quality release.\n\nSince the first beta release, we’ve mostly been focused on stability, bugfixes, and improving the key focus areas of this release: coroutine support and the JavaScript backend. The full list of changes since 1.1 Beta can be found in the [changelog](https://github.com/JetBrains/kotlin/blob/0e1b61b422bd0d006158d8b68fa34e960853c5c6/ChangeLog.md). And if you’re interested in a recap of everything added in version 1.1, check out our [what’s new page](https://kotlinlang.org/docs/reference/whatsnew11.html).\n\n## Migration Notes\n\nFor JavaScript projects, we’ve changed the name of the artifact for the standard library. Instead of `kotlin-js-library`, it is now `kotlin-stdlib-js`. You’ll need to update your Maven and Gradle scripts accordingly when you update to 1.1 beta 2 or a newer build.\n\nIn addition to that, testing support classes (in the package `kotlin.test`) for JavaScript are now packaged as a separate artifact, as it was previously done for the Java version. If you’re using kotlin.test in your JS project, add a dependency on `kotlin-test-js`.\n\nThe coroutines APIs in the Kotlin standard library have been moved to the `kotlin.coroutines.experimental` package; you need to update your imports if you’ve used these APIs in your code. See [Andrey’s forum post](https://discuss.kotlinlang.org/t/experimental-status-of-coroutines-in-1-1-and-related-compatibility-concerns/2236) for the background on this change.\n\nWe’ve also made it easier to enable the experimental coroutine support in your Gradle projects. Instead of editing gradle.properties, you can add the following snippet to your build.gradle:\n\n```kotlin\nkotlin {\n experimental {\n coroutines 'enable'\n }\n}\n```\n\nIf you’re using the [kotlinx.coroutines library](https://github.com/kotlin/kotlinx.coroutines), please update your dependency to version `0.6-beta`. Earlier versions of the library are incompatible with this Kotlin update.\n\n## New Features\n\nWe did add a few last-minute features in this beta. Here are the most important ones:\n\n* The compiler now reports a warning if you declare an extension that has the same signature as a member of the same class and will always be shadowed (for example, `String.length()`)\n* Type inference for member references passed to generic functions is now much improved ([KT-10711](https://youtrack.jetbrains.com/issue/KT-10711))\n* The `minus` operator can now be used with maps, returning a copy of the map with the given keys removed. The `-=` operator can be used on mutable maps to remove the given keys from the map.\n* It is now possible to access the delegate instance of a delegated property using `KPropertyN.getDelegate()` (see [KT-8384](https://youtrack.jetbrains.com/issue/KT-8384) for details);\n* Intention (contributed by Kirill Rakhman) to merge two nested `if` statements;\n* Support for building Android projects when the Jack toolchain is enabled (`jackOptions { true }`);\n* Intention (contributed by Kirill Rakhman) to generate `View` constructors in Android applications.\n\n## Source Compatibility with Kotlin 1.0\n\nAnother area to which we paid a lot of attention in this update is **source compatibility with Kotlin 1.0**. This allows you to try Kotlin 1.1, even if your team is using Kotlin 1.0, without worrying that you’ll break the build by using some of the features added in the new release.\n\nTo enable the compatibility mode:\n\n* For Maven, Ant and the command-line compiler, set the `-language-version` compiler argument to 1.0.\n* In a Gradle build, add `kotlinOptions { languageVersion = \"1.0\" }` to your `compileKotlin` task.\n* In the IDE, specify the language version in the Kotlin facet settings or in Settings | Build, Execution, Deployment | Compiler | Kotlin Compiler\n\n## How to try it\n\n**In Maven/Gradle:** Add `http://dl.bintray.com/kotlin/kotlin-eap-1.1` as a repository for the build script and your projects; use `1.1.0-beta-38` as the version number for the compiler and the standard library.\n\n**In IntelliJ IDEA:** Go to _Tools → Kotlin → Configure Kotlin Plugin Updates_, then select “Early Access Preview 1.1” in the _Update channel_ drop-down list, then press _Check for updates_.\n\nThe command-line compiler can be downloaded from the [Github release page](https://github.com/JetBrains/kotlin/releases/tag/v1.1-beta2).\n\n**On [try.kotlinlang.org](http://try.kotlinlang.org/)**. Will be available soon.\n\nLet’s Kotlin!\n","author":"Dmitry Jemerov","date":"2017-02-02","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"PultusORM : Sqlite ORM for Kotlin","url":"https://medium.com/@sakibsami/https-medium-com-sakibsami-pultusorm-sqlite-orm-for-kotlin-2e01ed9ddcf6#.645u2wr6n","body":"\nFew days back I was developing a Kotlin desktop application and needed a database system like Sqlite to store data. I started searching on google & github for a Sqlite ORM library and after spending few hours I figure out [some library](https://github.com/Heapy/awesome-kotlin#database) but no one fulfil my requirements. So I decide to write one by myself. As I am too lazy so I tried to develop something easier and straightforward. I don’t want the developer to write some queries and use the ORM system. So I develop the library keep in mind that not only me but everyone needs something easy, something more handy, something more flexible which will do everything. Ok I have started writing PultusORM a sqlite ORM library for Kotlin.\n\n[PultusORM](https://github.com/s4kibs4mi/PultusORM) is an opensource project available on github under MIT license.\n\nInstallation is as easy as eating a slice of pizza ;) [Have a look](https://github.com/s4kibs4mi/PultusORM#usages).\n\nIf you are done with installation move forward to write some code & query some data.\n\nLike other application you don’t need to write a model class extending any other class -_- I am too lazy to extend something :/ . So what do you have to do ? Just write a class having some properties (Must be primitive types till now). Initiate a connection with the database just by providing database name or alone with database path, everything else handled for you.\n\n```kotlin\nclass Post {\n @PrimaryKey\n @AutoIncrement\n var postId: Int = 0\n var postTitle: String? = null\n var postAuthor: String? = null\n}\n\nval pultusORM: PultusORM = PultusORM(\"blog.db\") // specifying path is optional\nval post: Post = Post()\npost.postTitle = \"Welcome to Kotlin\"\npost.postAuthor = \"Sakib Sami\"\n\npultusORM.save(post) // Table will be created on fly if not exists\n```\n\nSometimes I feel like queries should be async which will give me a callback with execution result. Well you have that option in PultusORM. All queries having callback option are async. For this you just need to implement Callback interface and pass it as callback parameter, its that simple. Do you still think eating pizza is more easier than this ? Maybe not !!!\n\nOk tired of eating pizza ? need some drinks ? Lassi is my favourite. Maybe you don’t dislike it but you have other options. In PultusORM there are lots of option for data retrieval. You can fetch all data of a specific class. Or you can fetch based on some options. Options like **equal, not equal, and, or, in, between, less, greater, sort, group** are ready for you. Not enough !!! want some more mouthwatering ? Feel free to [create a issue](https://github.com/s4kibs4mi/PultusORM/issues/new).\n\nLunch time is so confusing.I think should I eat some pizza or rice !!! But I like both. So day by day I keep changing food items. PultusORM also provide you data update support using all the condition options above as well as callback option which is async.\n\nAfter reading this article you may want to delete this as its too boring !!! In medium you can’t but PultusORM won’t disappoint you. You have option to delete data from data store.\n\nIf you wish you can see the full [menu card](https://github.com/s4kibs4mi/PultusORM/wiki). Hope you will love developing apps using it.\n\nRepository : [https://github.com/s4kibs4mi/PultusORM](https://github.com/s4kibs4mi/PultusORM)\n\nWiki : [https://github.com/s4kibs4mi/PultusORM/wiki](https://github.com/s4kibs4mi/PultusORM/wiki)\n\n","author":"Sakib Sami","date":"2016-10-07","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Lang","url":"https://speakerdeck.com/developer/kotlin-lang","body":"\n\n[Slides](https://speakerdeck.com/developer/kotlin-lang)\n\n","author":"Jemo Mgebrishvili","date":"2016-11-20","type":"slides","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Neural Networks in Kotlin (part 2)","url":"http://beust.com/weblog/2016/05/30/neural-networks-in-kotlin-part-2/","body":"\nIn the [previous installment](http://beust.com/weblog/2016/05/27/neural-network-in-kotlin/), I introduced a mystery class `NeuralNetwork` which is capable of calculating different results depending on the data that you train it with. In this article, we’ll take a closer look at this neural network and crunch a few numbers.\n\n## Neural networks overview\n\nA neural network is a graph of neurons made of successive layers. The graph is typically split in three parts: the leftmost column of neurons is called the “input layer”, the rightmost columns of neurons is the “output layer” and all the neurons in-between are the “hidden” layer. This hidden layer is the most important part of your graph since it’s responsible for making the calculations. There can be any numbers of hidden layers and any number of neurons in each of them (note that the Kotlin class I wrote for this series of articles only uses one hidden layer).\n\nEach edge that connects two neurons has a weight which is used to calculate the output of this neuron. The calculation is a simple addition of each input value multiplied by its weight. Let’s take a look at a quick example:\n\n![](https://docs.google.com/drawings/d/1lnkGCoJ5DsJcXlqXnjmE0oGM6l1wHrf9pRuN-8ZU7Xc/pub?w=480&h=360) \n\nThis network has two input values, one hidden layer of size two and one output. Our first calculation is therefore:\n\n```kotlin\nw11-output = 2 * 0.1 + (-3) * (-0.2) = 0.8\nw12-output = 2 * (-0.4) + (-3) * 0.3 = -1.7\n```\n\nWe’re not quite done: the actual outputs of neurons (also called “activations”) are typically passed to a normalization function first. To get a general intuition for this function, you can think of it as a way to constrain the outputs within the [-1, 1] range, which prevents the values flowing through the network from overflowing or underflowing. Also, it’s useful in practice for this function to have additional properties connected to its derivative but I’ll skip over this part for now. This function is called the “activation function” and the implementation I used in the `NeuralNetwork` class is the [hyperbolic tangent, `tanh`](http://mathworld.wolfram.com/HyperbolicTangent.html).\n\nIn order to remain general, I’ll just refer to the activation function as `f()`. We therefore refine our first calculations as follows:\n\n```kotlin\nw11-output = f(2 * 0.1 + (-3) * (-0.2))\nw12-output = f(2 * (-0.4) + (-3) * 0.3)\n```\n\nThere are a few additional details to this calculation in actual neural networks but I’ll skip those for now.\n\nNow that we have all our activations for the hidden layer, we are ready to move to the next layer, which happens to be the ouput layer, so we’re almost done:\n\n```kotlin\noutput = f(0.1 * w11-output - 0.2 * w12-output\n = 0.42\n```\n\nAs you can see, calculating the output of a neural network is fairly straightforward and fast, much faster than actually training that network. Once you have created your networks and you are satisfied with its results, you can just pass around the characteristics of that network (weights, sizes, ...) and any device (even phones) can then use that network.\n\n## Revisiting the xor network\n\nLet’s go back to the `xor` network we created in the first episode. I created this network as follows:\n\n```kotlin\nNeuralNetwork(inputSize = 2, hiddenSize = 2, outputSize = 1)\n```\n\nWe only need two inputs (the two bits) and one output (the result of `a xor b`). These two values are fixed. What is not fixed is the size of the hidden layer, and I decided to pick 2 here, for no particular reason. It’s interesting to tweak these values and see whether your neural network performs better of worse based on these values and there is actually a great deal of both intuition and arbitrary choices that go into these decisions. These values that you use to configure your network before you run it are called “hyper parameters”, in contrast to the other values which get updated while your network runs (e.g. the weights).\n\nLet’s now take a look at the weights that our `xor` network came up with, which you can display by running the Kotlin application with --log 2:\n\n```plain\nInput weights:\n-1.21 -3.36\n-1.20 -3.34\n1.12 1.67\n \nOutput weights:\n3.31\n-2.85 \n```\n\nLet’s put these values on the visual representation of our graph to get a better idea:\n\n![](https://docs.google.com/drawings/d/1vzNDxpKkIP0h6pp8KglUn55a-pLE5PIAaO204ZNqYR0/pub?w=960&h=720) \n\nYou will notice that the network above contains a neuron called “bias” that I haven’t introduced yet. And I’m not going to just yet besides saying that this bias helps the network avoid edge cases and learn more rapidly. For now, just accept it as an additional neuron whose output is not influenced by the previous layers.\n\nLet’s run the graph manually on the input (1,0), which should produce 1:\n\n```kotlin\nhidden1-1 = 1 * -1.21\nhidden1-2 = 0 * -1.20\nbias1 = 1 * 1.12\n \noutput1 = tanh(-1.21 + 1.12) = -0.09\n \nhidden2-1 = 1 * -3.36\nhidden2-2 = 0 * -3.34\nbias2 = 1 * 1.67\n \noutput2 = tanh(-3.36 + 1.6) = -0.94\n \n// Now that we have the outputs of the hidden layer, we can caculate\n// our final result by combining them with the output weights:\n \nfinalOutput = tanh(output1 * 3.31 + output2 * (-2.85))\n = 0.98\n```\n\nWe have just verified that if we input `(0,1)` into the network, we’ll receive `0.98` in output. Feel free to calculate the other three inputs yourself or maybe just run the `NeuralNetwork` class with a log level of 2, which will show you all these calculations.\n\n## Revisiting the parity network\n\nSo the calculations hold up but it’s still a bit hard to understand where these weights come from and why they interact in the way they do. Elucidating this will be the topic of the next installment but before I wrap up this article, I’d like to take a quick look at the parity network because its content might look a bit more intuitive to the human eye, while the `xor` network detailed above still seems mysterious.\n\nIf you train the parity network and you ask the `NeuralNetwotk` class to dump its output, here are the weights that you’ll get:\n\n```plain\nInput weights:\n0.36 -0.36\n0.10 -0.09\n0.30 -0.30\n-2.23 -1.04\n0.57 -0.58\n \nOutput weights:\n-1.65\n-1.64 \n``` \n\nIf you pay attention, you will notice an interesting detail about these numbers: the weights of the first three neurons of our hidden layer cancel each other out while the two inputs of the fourth neuron reinforce each other. It’s pretty clear that the network has learned that when you are testing the parity of a number in binary format, the only bit that really matters is the least significant one (the last one). All the others can simply be ignored, so the network has learned from the training data that the best way to get close to the desired output is to only pay attention to that last bit and cancel all the other ones out so they don’t take part in the final result.\n\n## Wrapping up\n\nThis last result is quite remarkable if you think about it, because it really looks like the network learned how to test parity at the formal level (“The output of the network should be the value of the least significant bit, ignore all the others”), inferring that result just from the numeric data we trained it with. Understanding how the network learned how to modify itself to reach this level will be the topic of the next installment of the series.\n\n","author":"Cédric Beust","date":"2016-05-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Easy DSL design with Kotlin","url":"https://blog.frankel.ch/easy-dsl-design-with-kotlin/","body":"\nIn Android, every tutorial teaching you the basics describe how to design screen through XML files. It’s also possible to achieve the same result with Java (or any JVM-based language). Android screen design is not the only domain where XML and Java are valid options. For example, Spring configuration and Vaadin screen design allow both. In all those domains, there’s however a trade-off involved: on one hand, XML has a quite rigid structure enforced by an XML-schema while Java gives power to do pretty well anything at the cost of readability. “With great power comes great responsibility”. In the latter case, it’s up to the individual developer to exercise his/her judgement in order to keep the code as readable as possible.\n\n[Domain-Specific Languages](https://en.wikipedia.org/wiki/Domain-specific_language) sit between those two ends of the spectrum, as they offer a structured syntax close to the problem at hand but with the full support of the underlying language constructs when necessary. As an example, the AssertJ library provides a DSL for assertions, using a fluent API. The following snippet is taken from its documentation:\n\n```kotlin\n// entry point for all assertThat methods and utility methods (e.g. entry)\nimport static org.assertj.core.api.Assertions.*;\n\n// collection specific assertions (there are plenty more)\n// in the examples below fellowshipOfTheRing is a List\nassertThat(fellowshipOfTheRing).hasSize(9)\n .contains(frodo, sam)\n .doesNotContain(sauron);\n```\n\nDSLs can be provided in any language, even if some feel more natural. Scala naturally comes to mind, but Kotlin is also quite a great match. Getting back to Android, Jetbrains provides the excellent Anko library to design Android screen using a Kotlin-based DSL. The following snippet highlights Anko (taken from the doc):\n\n\n\n```kotlin\nverticalLayout {\n val name = editText()\n button(\"Say Hello\") {\n onClick { toast(\"Hello, ${name.text}!\") }\n }\n}\n```\n\nThere are two Kotlin language constructs required for that.\n\n## Extension functions\n\nI already wrote about extension functions, so I’ll be pretty quick about it. In essence, [extension functions](/extension-functions-for-more-consistent-apis/) are a way to add behavior to an **existing** type.\n\nFor example, `String` has methods to set in lower/upper case but nothing to capitalize. With extension functions, it’s quite easy to fill the gap:\n\n```kotlin\nfun String.toCapitalCase() = when {\n length < 2 -> toUpperCase()\n else -> this[0].toUpperCase() + substring(1).toLowerCase()\n}\n```\n\nAt this point, usage is straightforward: `\"foo\".toCapitalCase()`.\n\nThe important point is the usage of `this` in the above snippet: it refers to the actual string instance.\n\n## Function types\n\nIn Kotlin, function **are** types. Among all consequences, this means functions can be passed as function parameters.\n\n```kotlin\nfun doSomethingWithInt(value: Int, f: (Int) -> Unit) {\n value.apply(f);\n}\n```\n\nThe above function can be now passed any function that takes an `Int` as a parameter and returns `Unit` _e.g._ `{ print(it) }`. It’s called like that:\n\n```kotlin\ndoSomethingWithInt(5, { print(it) })\n```\n\nNow, Kotlin offers syntactic sugar when calling methods: if the lambda is the **last** parameter in a function call, it can be separated from the other arguments like this:\n\n```kotlin\ndoSomethingWithInt(5) { print(it) }\n```\n\n## Putting it all together\n\nGetting back to the [Anko snippet above](#anko), let’s check how the `verticalLayout { ... }` method is defined:\n\n```kotlin\ninline fun ViewManager.verticalLayout(theme: Int = 0, init: _LinearLayout.() -> Unit): LinearLayout {\n return ankoView(`$Anko$Factories$CustomViews`.VERTICAL_LAYOUT_FACTORY, theme, init)\n}\n```\n\nAs seen in the first paragraph, the `init` parameter is an extension function defined on the `_LinearLayout` type. `this` used in its context will refer to the instance of this latter type.\n\nThe second paragraph explained what represents the content of the braces: the `init` parameter function.\n\n## Conclusion\n\nHopefully, this post show how easy it is to create DSL with Kotlin thanks to its syntax.\n\nI developed one such DSL to create GUI for the [Vaadin](https://vaadin.com/) framework: the name is Kaadin and the result is [available online](https://nfrankel.github.io/kaadin/).\n\n","author":"Nicolas Fränkel","date":"2016-10-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Exploring an Either Monad in Kotlin","url":"https://blog.exallium.com/exploring-an-either-monad-in-kotlin-92618b9c4623#.nlt1cxd96","body":"\nRecently, I was enlightened. I finally, fully grasped how the Either Monad works. At least I think I do. In this post, I am looking to report my findings, both for the education of others of this powerful tool, as well as to see if my understanding of this monadic concept really holds water.\n\n### What’s an Either Monad?\n\nAn Either Monad consists of two basic types, Left and Right. It is, essentially, the If/Else statement of the Monad world. Left signifies that something went wrong, while Right signifies that things are working as they should. Just remember, that you want your code to be all right. As the monad passes through different bindings and is worked with, it can either report a Left, and, essentially, skip the rest of the call chain, or it can report Right and continue in fashion.\n\n### But wait, what’s a Monad?\n\nThink of a Monad as a box. In this box, you can store stuff. A Monad is simply a data wrapper with a few different, unifying properties. For example, the Java8 Optional is considered a Monad, as is Kotlin’s ? types and Haskell’s Maybe, among others.\n\nMonads follow some simple rules. They include two sequencing functions, a return function and a fail function. The sequencing functions are, in my example, noted as bind and seq.\n\nBind will take a Monad and, if all is well, apply a function to it’s contents, and return another Monad of the same general type. For example, an Either Monadic bind operation will always return another Either Monad, though the type of the data being wrapped might have changed, say from int to bool.\n\nSeq will take a Monad and return the monad passed to it. It is a way to finish a chain of operations and ignore the result, and instead pick up from a new source Monad.\n\nReturn simply takes a variable, and returns it wrapped in a new Monad.\n\nFail takes a string, and throws an exception with it as the message. It’s type returns the Monad in question in order to be compliant with the bind function.\n\nAn example, written in Kotlin:\n\n```kotlin\nsealed class Either {\n class Left(val l: L) : Either() {\n override fun toString(): String = \"Left $l\"\n }\n \n class Right(val r: R) : Either() {\n override fun toString(): String = \"Right $r\"\n }\n \n infix fun bind(f: (R) -> (Either)): Either {\n return when (this) {\n is Either.Left -> Left(this.l)\n is Either.Right -> f(this.r)\n }\n }\n \n infix fun seq(e: Either): Either = e\n \n companion object {\n fun ret(a: R) = Either.Right(a)\n fun fail(msg: String): Either.Right = throw Exception(msg)\n }\n}\n```\n\nHere, we have a Sealed class. This is because we only ever want to have two options for the Either monad, Left or Right. Each of these simply define a toString method, for convenience.\n\nWe have two methods within either, which represent the aforementioned bind and sequence functions. (In Haskell, these are (>>=) and (>>), respectively). These are infix methods, who’s usage is explained in the sample usage code below.\n\nThe bind method simply takes a function. If the Either in context is Left, we simply return a Left of proper type. If it is Right, then we apply the function to it.\n\nThe seq method simply returns whatever its input is.\n\nWe then have the two other functions required for a monad defined as static functions, as these are “creation” methods. Ret simply returns a new Right instance for whatever value is passed in a. Fail throws an exception with the message as defined in the parameter.\n\nRet is a convenience function for creating new Rights. Fail is a convenience function for throwing basic exceptions. For example, you can easily fail from within a bind, as shown in usage.\n\n### Using this class\n\nHere are some examples of usage. Note the use in some places of bind as an infix operator. Also note that there is a lot of Type parameters in the code. This is due to Either needing to know information about both the left and right hand side of a given instance. I believe that this is ok. It’s not as concise as I would like it to be, but it’s a trade-off for strong typing.\n\n```kotlin\nfun main(args: Array) {\n \n // Simple bind, from one R type to another\n println(Either.Right(5) bind { it -> Either.ret(true)} )\n \n // Simple bind, demonstrating left pass-through\n println(Either.Left(\"error\").bind({ it -> Either.ret(it + 1) }))\n \n // Simple bind, demonstrating conditions\n val right = Either.Right(5)\n val condition = { it: Int -> if (it > 3) {\n Either.Left(\"number is too big\")\n } else {\n Either.Right(it * 2)\n }}\n \n // Examples utilizing this condition.\n println(right bind condition)\n println(Either.Right(2).bind(condition).bind(condition).seq(Either.Right(2.0f)))\n \n // Demonstration of Fail\n try {\n println(Either.Right(5) bind { Either.fail(\"asdf\") })\n } catch (e: Exception) {\n println(\"exception: ${e.message}\")\n }\n}\n```\n\n### Monads as a concept, not a base class\n\nOne mistake often made when someone is learning about Monads is that there should be some sort of Monad base class. I believe that this is driven by backgrounds in object oriented programming. OOP does not translate very well into a functional context. While there is definitely a class definition of a Monad in Haskell, because of the differences in the language, functional paradigm, and really just the strength and power of the Haskell type system, it does not translate well to a Java interface. Specifically when the data within the Monad changes, the type system is lacking in some ways to completely express, say, the bind function, when we move from an R value of Int to an R value of boolean.\n\nThus, Monads should be understood as a general concept, not as some base class we extend. They are not really meant to be interoperable with each other. Each Monad is a unique tool that provides it’s own benefits, such as the aforementioned Java8 Optional, or Haskell’s State monad. Each would need to be explicitly written, and not be expected to co-mingle.\n\n### Conclusion\n\nMonads are powerful. Really powerful. They’ve started to take the OOP world by storm, from simple language conventions like Nullability in Kotlin, to the advent of RxJava over the last year or so. As we move into a more multi-processed world, where core count continues to rise and processor speeds continue to stagnate, it will be more important than ever to understand Functional programming concepts, whether it be immutability, pure functions, or this, the Monad.\n\nThanks for reading.\n\n","author":"Alex Hart","date":"2016-11-22","type":"article","categories":["Kotlin","FP"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"JDK7/8 features in Kotlin 1.0","url":"https://discuss.kotlinlang.org/t/jdk7-8-features-in-kotlin-1-0/1625","body":"\nCurrently it's rather inconvenient to use those methods of mapped builtin types, that were added in JDK8. These include `Collection.stream()`, `Map.getOrDefault(K, V)`, etc. We have several long-standing issues related in our tracker: [KT-9194](https://youtrack.jetbrains.com/issue/KT-9194), [KT-5175](https://youtrack.jetbrains.com/issue/KT-5175) and [KT-10864](https://youtrack.jetbrains.com/issue/KT-10864).\n\nThis happens because Kotlin targets JDK 1.6 as the minimum JDK version, so it can't expose those members of builtin types that are not available in JDK 1.6.\nWe plan to remove the limitation in Kotlin 1.1 by exposing all builtin type members available in the target platform (excluding some blacklisted exceptions), but as a short-term fix we could provide a way to call these methods via extensions.\n\nWe have collected those extensions in a small Kotlin library: [kotlinx.support](https://github.com/Kotlin/kotlinx.support).\nIt consists of two artifacts: **kotlinx-support-jdk8** and **kotlinx-support-jdk7**. The former has a dependency on the latter, so if you target JDK8 you could only reference kotlinx-support-jdk8 and have the latter as a transitive dependency.\n\nThese artifacts are available for downloading from the maven repository on bintray [https://bintray.com/kotlin/kotlinx.support/kotlinx.support](https://bintray.com/kotlin/kotlinx.support/kotlinx.support) and also on jcenter [https://bintray.com/bintray/jcenter?filterByPkgName=kotlinx.support](https://bintray.com/bintray/jcenter?filterByPkgName=kotlinx.support).\n\n### kotlinx-support-jdk8\n\nThis library provides extensions to call default methods of collection interfaces introduced in JDK8.\n\n```kotlin\nimport kotlinx.support.jdk8.collections.*\nimport kotlinx.support.jdk8.text.*\n\n// some quite more verbose way to say 'listOf().flatMap { it.asIterable() }'\nval chars = listOf(\"abc\", \"def\").stream()\n .flatMap { it.chars().boxed().map { it.toChar() } }\n .collect(Collectors.toList())\n```\n\n### kotlinx-support-jdk7\n\nThis library exposes `Throwable` methods to work with suppressed exceptions, and introduces [long-awaited](https://youtrack.jetbrains.com/issue/KT-5899) `use` extension for `AutoCloseable`. Note that this `use` being imported explicitly has precedence over `use` from Standard Library and thus can be used for `Closeable` as well.\n\n```kotlin\nimport kotlinx.support.jdk7.use\n\nclass Resource(val faultyClose: Boolean = false) : Closeable {\n\n override fun close() {\n if (faultyClose)\n throw IOException(\"Close failed\")\n }\n}\n\n// the IOException thrown by 'close' would be added\n// to the list of suppressed exceptions of IllegalStateException\n// thrown from lambda passed to 'use'\nval result = Resource(faultyClose = true).use {\n throw IllegalStateException(\"operation failed\")\n}\n```\n\n","author":"Ilya Gorbunov","date":"2016-04-21","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin — Love at first line","url":"https://medium.com/@dime.kotevski/kotlin-love-at-first-line-7127befe240f#.p5hp6dxlh","body":"\n## Kotlin — Love at first line\n\nKotlin 1.0 has been [released](https://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/)\n a few days ago and it’s time to check out its awesome features.\n\nFor those of you who might have been living under a rock and don’t know what Kotlin is — Kotlin is a new JVM programming language that tries to “fill in the gaps” that Java has. It’s 100% interoperable with Java — meaning that you can have a mixed project that contains Kotlin & Java classes. The classes are compiled to Java bytecode, and that bytecode is “runnable” on Java6+, which makes it runnable on Android.\n\nThe language is awesome, and combined with the [Anko](https://github.com/Kotlin/anko) library it’s even [awesome-er*](http://www.urbandictionary.com/define.php?term=Awesome-er). I won’t be explaining the syntax of the language (for that you have the official [page](https://kotlinlang.org/)). I’m just going to try and expose a few of it’s awesome features.\n\n### [Single-Expression functions](https://kotlinlang.org/docs/reference/functions.html#single-expression-functions)\n\nIf we have a function that boils down to a single expression, we can use the single-expression function syntax:\n\n override fun equals(other: Any?) = other is Task && other.id == id\n\n### [Extensions](https://kotlinlang.org/docs/reference/extensions.html)\n\nExtensions allow us to extend any existing class by adding functions and properties without the need to inherit from that class.\n\n```kotlin\nfun ViewGroup.inflate(\n @LayoutRes layoutRes: Int,\n attachToRoot: Boolean = false) =\n\n LayoutInflater\n .from(context)\n .inflate(layoutRes, this, attachToRoot)\n```\n\nThe extension function above adds the **.inflate(...)** method to the ViewGroup class, so instead of doing this every time:\n\n\n```kotlin\nval view = LayoutInflater\n .from(parent)\n .inflate(R.layout.todo_list_item, parent, false)\n```\n\nnow we can just do this:\n\n\n```kotlin\nval view = parent.inflate(R.layout.todo_list_item)\n```\n\nor:\n\n\n```kotlin\nval view = parent.inflate(R.layout.todo_list_item,\n attachToRoot = true)\n```\n\nI guess you already noticed that Kotlin also supports [default arguments](https://kotlinlang.org/docs/reference/functions.html#default-arguments).\n\n### [Lambda](https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions)\n\nIntentionally left blank.\n\n### [Optionals / Null safety](https://kotlinlang.org/docs/reference/null-safety.html)\n\nForget about NullPointerExceptions. Kotlin has 2 types of variables, nullable and non-nullable. If we declare our variable as non-nullable — the compiler won’t let us assign a null value to it. Only nullable variables can be null.\n\n\n```kotlin\nvar nonNullable: String = \"This is a title\" // Non-nullable variable\nvar nullable: String? = null // Nullable variable\n```\n\nIn case of the *nonNullable* variable, we can safely call methods on it, without any null checks, because it *cannot have a null value*.\n\nIn case of the *nullable* variable, we can safely call methods with the help of the *safe-trasversal operator (?.)*, and forget about null checks:\n\n\n```kotlin\nval length = nullable?.length\n```\n\nThe code above won’t fail, even if the *nullable* variable has a null value. In that case, the value of the *length* variable will be *null*.\n\n### [Elvis operator](https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator)\n\nThe result of a **safe call (?.)** is always a nullable variable. So in cases where we are calling a method on a null variable — the result will be null.\n\nThat can be inconvenient sometimes. For example, in the code sample above, we want our **length** variable to be a non-null variable because it’s logical for it to have a value of 0 in case of a null string.\n\nIn cases like that, we can use the **elvis operator ( ?: )**.\n\n\n```kotlin\nval length = nullable?.length ?: 0\n```\n\nThe elvis operator will use the left side value if it’s not null. In case the left side value is null, it will use the right non-nullable value.\n\nYou can even use it to make your sanity checks more readable.\n\n\n```kotlin\n ...\n}\n```\n\nWith help of the elvis operator, the same method in Kotlin will look like this:\n\n\n```kotlin\npublic fun myMethod(str: String?) {\n // Sanity check\n str ?: return\n\n ...\n}\n```\n\nThe great part of using this is that the compiler will **smart cast** our **str** variable to a non-nullable variable after the “*str ?: return*” line.\n\n### [Optional getters/setters](https://kotlinlang.org/docs/reference/properties.html#properties-and-fields)\n\nUnlike in Java, where we are used to define all of our class properties **_private_** and write getters and setters, in Kotlin we write getters and setters only if we want to have some custom behaviour.\n\nThe simplest definition looks like this:\n\n\n```kotlin\nclass Task {\n var completed = false\n}\n```\n\nAnd we can access the property:\n\n\n```kotlin\nval task = Task()\nif (task.completed) ...\n```\n\nIf we wan’t to expose just the getter and allow setting the value only from within the class:\n\n\n```kotlin\nvar completed = false\n private set\n```\n\nAnd if we want to have completely custom behaviour:\n\n\n```kotlin\nvar completedInt = 0\nvar completed: Boolean\n get() = completedInt == 1\n set(value) { completedInt = if (value) 1 else 0 }\n```\n\n### [Lazy properties](https://kotlinlang.org/docs/reference/delegated-properties.html#lazy)\n\nKotlin allows us to declare lazy properties — properties that are initialized when we first access them.\n\n\n```kotlin\nprivate val recyclerView by lazy {\n find(R.id.task_list_new)\n}\n```\n\nWhen we first access the **recyclerView** property, the lambda expression is evaluated and the returned value from the lamdba is saved and returned in that and every subsequent call.\n\n### [Observable properties](https://kotlinlang.org/docs/reference/delegated-properties.html#observable)\n\nIn Kotlin we can observe properties. The syntax for declaring such properties is the following:\n\n\n```kotlin\nvar tasks by Delegates.observable(mutableListOf()) {\n prop, old, new ->\n notifyDataSetChanged()\n dataChangedListener?.invoke()\n}\n```\n\nThis means that we are going to be notified every time the value of our property changes (the provided lambda will be called).\n\n\n## [Anko extensions](https://github.com/Kotlin/anko)\n\nAnko is a great library and has a lot of great extensions. I will list a couple.\n\n### find(id: Int)\n\nIt replaces the findViewById(int id) method. This extension function returns the view already cast to the given type T, so there is no need to cast it.\n\n\n```kotlin\nval recyclerView = find(R.id.task_list_new)\n```\n\n### [SQLite](https://github.com/Kotlin/anko/blob/master/doc/SQLITE.md#anko-heart-sqlite)\n\nAnko has great support for SQLite databases. For a complete overview, check their [guide](https://github.com/Kotlin/anko/blob/master/doc/SQLITE.md#anko-heart-sqlite). I will just show you one example:\n\n\n```kotlin\nfun allTasks() = use {\n select(table)\n .orderBy(completed)\n .orderBy(priority, SqlOrderDirection.DESC)\n .exec {\n parseList(parser)\n }\n}\n```\n\nThe **use {...}** function opens the database for us, and closes it after the given lambda executes. So we don’t have to worry about closing it anymore and can forget about all those **try {...} catch(...) {...} finally {...}** blocks. Inside the lambda that we pass to the **use** function, **this** references our database. That is the power of Kotlin’s **type-safe builders**. Read more about them [here](http://blog.jetbrains.com/kotlin/2011/10/dsls-in-kotlin-part-1-whats-in-the-toolbox-builders/) and [here](https://kotlinlang.org/docs/reference/type-safe-builders.html).\n\nThe **select(...)...exec {}** call chain, selects data from the database. And the **parseList(parser)** call parses the rows of data and returns a list of objects, that our **parser** returns. The definition of our **parser** is:\n\n\n```kotlin\nval parser = rowParser {\n id: Int, name: String, priority: Int, completed: Int ->\n Task(id, name, priority, completed)\n}\n```\n\n","author":"Dimitar Kotevski","date":"2016-02-21","type":"article","categories":["Anko","Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"A Developer’s Look at Kotlin","url":"http://insights.dice.com/2016/09/09/developers-look-kotlin/","body":"\n![shutterstock_379642018](http://insights.dice.com/wp-content/uploads/2016/09/shutterstock_379642018.jpg)\n\nNamed after an island near St. Petersburg, Russia (take a gander at its spectacular sunset, above), [Kotlin](https://kotlinlang.org/) is a statically typed open-source programming language that runs on the JVM, just like Java. JetBrains released version 1 in February 2016, after five years of development.\n\nOriginally coded by a team of Russian developers, Kotlin positions itself as an industrial-strength object-oriented language superior to Java. It uses Java code from the existing Java Class Library, and developers can use it to develop Android apps or generate JavaScript source code. You [can run it online in Intelli Idea](http://try.kotlinlang.org/#/Examples/Hello,%20world!/Simplest%20version/Simplest%20version.kt), the JetBrains IDE.\n\nHere are some additional features that make Kotlin different from Java:\n\n### The Language\n\nWith Kotlin, a main function is needed at the package level:\n\n```kotlin\n// Simplest version\n\nfun main(args: Array) {\n println(\"Hello World!\")\n}\n\n// Second one with return type and returned value\n\nfun main(args: Array) : Int {\n println(\"Hello, world!\")\n return 0\n}\n```\n\nEither of the above works. (Comments are either /* .. */ for blocks or // for single lines, and you can nest block comments.) In the below, note how variable declarations are the Pascal way around; var means mutable (i.e., it can be changed), while val declares them read-only, so you must assign a value there:\n\n```kotlin\nval a: Int = 10000 // read-only\nval b: Int = 0x0F // hexadecimal read-only\nvar c = 0b1011 // binary also type inferred\n\nprintln(\"a = $a b = $b c = $c\")\n```\n\nThis outputs:\n\n```\na = 10000 b = 15 c = 11\n```\n\nNote that primitive types (Int etc) in Kotlin are objects (unlike in Java), so this works:\n\n```kotlin\nprintln(0x0e.toString())\n```\n\nSyntax is straightforward, but make sure that expressions have brackets. Ifs can be used as expressions or statements and blocks. Anything inside { } can have a value. Else is optional inside statements, but mandatory in expressions:\n\n```kotlin\nvar max: Int\n\nif (a > b)\n max = a\nelse\n max = b\n\n// Expression\n\nval max = if (a > b) a else b\n```\n\nThe switch statement is called when, but is more flexible, as it supports arbitrary expressions as constants:\n\n```kotlin\nfun cases(obj: Any) {\n\n when (obj) {\n 1 -> print(\"One\")\n \"Hello\" -> print(\"Greeting\")\n is Long -> print(\"Long\") // checks if type is long\n !is String -> print(\"Not a string\") if type is not a string\n else -> print(\"Unknown\")\n }\n}\n```\n\n### Objects and Classes\n\nThe example below shows a simple Dice class with a constructor that passes in the maximum dice value. Two private immutable properties hold the Java.util.Random instance and the maxvalue. Note that the declaration of the Random instance does not use new. A public function Roll() is called for Random; this uses the single line function form with = instead of return.\n\nIn the main function, an instance of this dice class is created and a for loop calls Roll() ten times:\n\n```kotlin\nimport java.util.Random;\n\nclass Dice (maxValue : Int) {\n private val rnd : Random = Random()\n private val maxvalue: Int\n \n init {\n maxvalue = maxValue\n }\n \n public fun Roll() : Int = rnd.nextInt(maxvalue) + 1\n}\n\nfun main(args: Array) : Unit {\n val dice: Dice= Dice(6)\n \n for (i in 1..10) {\n println(dice.Roll())\n }\n}\n```\n\nThe constructor (called a primary constructor) is part of the class header. It can’t contain any code except in an init { } section. It’s also possible to do this without init by initializing the maxvalue property directly; the init can then be removed.\n\n```kotlin\nprivate val maxvalue: Int = maxValue\n```\n\n### Delegated Properties\n\nProperties can have getters and setters, though immutable ones only get a getter. Usually properties are either reading from or writing to a backing field; getters and setters can extend this via delegated properties. The syntax of a class declaration in this case looks like this:\n\n```kotlin\nclass Example {\n var p: String by Delegate()\n}\n```\n\nThere are a couple of delegate types. Let’s start off with ‘Lazy’ for lazy initialization, which calls a lambda expression on the first access; this value is used on subsequent ones. Here’s lazy in use:\n\n```kotlin\nclass LazySample {\n var inc: Int = 10;\n val lazy: String by lazy {\n println(\"Assigned!\")\n (inc++).toString()\n }\n}\n\nfun main(args: Array) {\n val sample = LazySample()\n println(\"lazy = ${sample.lazy}\")\n println(\"lazy = ${sample.lazy}\")\n println(\"inc = ${sample.inc}\")\n}\n\n```\n\nThe output is:\n\n```\nAssigned!\nlazy = 10\nlazy = 10\ninc = 11\n```\n\nThis shows that despite accessing sample.lazy twice, only the first access initialized the value. If you comment out the three printlns and run it, you’ll see that there’s no assignment printed, as lazy is never assigned a value. That “by lazy” defers it until reading.\n\nNext up on the delegate types: ‘observable.’ In this example, a TaxRate value has been made ‘observable,’ and defaults to the value passed in: 18.5. But changing it explicitly invokes the handler, which prints out that it has changed. It can be very useful when you need to find out what is changing a property:\n\n```kotlin\nimport kotlin.properties.Delegates\n\nclass TaxRate {\n var value: Float by Delegates.observable(18.5f) { d, old, new ->\n println(\"Rate changed from $old% to $new%\")\n }\n}\n\nfun main(args: Array) {\n val rate = TaxRate()\n rate.value = 19.0f\n}\n\n```\n\nThis outputs:\n\n```\nRate changed from 18.5% to 19.0%\n```\n\n### Conclusions\n\nI’m a great believer that reduced cognitive load is good for programmers. It’s easier to understand code with simpler, more powerful syntax, and Kotlin certainly delivers on that.\n\nKotlin has been compared to Scala, though is somewhat simpler and compiles a lot faster. It’s not quite a snapshot of the language, [but the Idioms page](http://kotlinlang.org/docs/reference/idioms.html) tells you a lot about features and syntax in one go.\n\nAny developers wanting to know differences between Kotlin and Java at a glance can refer to the [Comparison to Java page](https://kotlinlang.org/docs/reference/comparison-to-java.html) via Kotlin’s reference materials.\n\n","author":"David Bolton","date":"2016-09-09","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Swift vs Kotlin for real iOS/Android apps","url":"http://angelolloqui.com/blog/38-Swift-vs-Kotlin-for-real-iOS-Android-apps","body":"\n\n[**Swift**](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/index.html) and [**Kotlin**](https://kotlinlang.org/docs/reference/) are two great languages for iOS and Android development respectively. They both have very **modern features and syntax** that can help enormously to build native apps. But, how do they both compare to each other? Are they similar? Can we reuse more code between platforms if we adopt them in our projects? \n\nThose are the questions we will explore in this post together with some real app code examples implementing the same features in both languages.\n\n### Side to side\n\nAs commented, both languages are very similar. In fact, they are so similar that **I will focus on the differences** rather than the similarities in this post. Before exploring the code samples, let’s cover **the most relevant ones** that will pop up when translating between them:\n\n* **Swift Enums are more powerful**: In Swift, enums are very powerful and first-class type. They can contain different associated values per case (discrete union types), computed properties and most of the features of `structs`. Because of that, it is frequent to see patterns like [the `Result` enum](https://www.natashatherobot.com/swift-generics-box/) that are not common in Kotlin due to language limitations (_UPDATE: A similar pattern can be implemented in Kotlin by [using `sealed class` instead of `enum`](https://kotlinlang.org/docs/reference/classes.html#sealed-classes), but it is more complicated that the Swift counterpart_)\n\n* **Swift has no `data class`**: One interesting construction in Kotlin is `data class`. It allows you to declare containers of information that automatically implement things like equality and copying. Very common pattern when dealing with plain objects that has no counterpart in Swift.\n\n* **Swift does not have delegated classes or delegated properties**: A very interesting feature of Kotlin are delegated classes and properties. With them, you can forward invocation of methods to another class automatically, or define behaviors for properties such as `lazy`, `obsrvable`, etc. You can even create your own property delegates. In Swift, things like `lazy` are modifiers implemented in the language, so that means that you can not create your own but you are limited to the ones provided.\n\n* **Swift does not allow annotations**: Coming from the Java world, Kotlin has full support for annotations. However, in Swift that is not considered at all, so annotations like `@Inject` or `@Test` that are so common in Java libraries do not have any counterpart in Swift.\n\n* **Kotlin classes are final by default**: Kotlin classes are by default closed for extension, so you have to add `open` in any class you expect to be extended with inheritance.\n\n* **Kotlin has no `struct` or passing data by value**: In Swift you can decide whether to use a `class` or a `struct` for your data. The decision is not trivial, and results in different implementation details. Structs are always passed by value, meaning that every time you call a method with it, return a struct, assign a struct,... the values are actually copied to the new variable, and any modification will only affect the modified variable and not the others. Besides that, structs do not allow inheritance, so they tend to be a perfect candidate for data classes. In Kotlin, there is no `struct` type and the language follows the same pattern than Java, where basic types (String, Int,...) are passed by value, but the rest are passed by reference.\n\n* **Kotlin has no tuples**: Tuples are not implemented in Kotlin, so you will find yourself creating small `data classes` as counterpart for Swift tuples.\n\n* **Kotlin has no `typealias`**: I just found out that it is in the roadmap for 1.1 but at the moment (Kotlin 1.0.4) there is no `typealias`, so patterns like the one I explained [in this previous post](http://angelolloqui.com/blog/37-Swifty-names-for-modules-protocols-and-implementation-classes) are not possible yet.\n\n* **Kotlin has no `guard` statement**: In Swift, `guard` statements are a more expressive way for checking conditions of some function than the standard `if` sentence. In Kotlin, you need to stay with the `if` check and reverse the condition.\n\nThere are also other differences when comparing both languages. Things like exceptions, pattern matching, constructors, `if let` sentences, loop iteration, casting,... work in slightly different ways, but in general they follow the same principles and they have very similar syntaxes.\n\nOne last difference to mention when working for iOS/Android is that the Operative System offers different **runtime environments and libraries to developers**. A couple of points to highlight:\n\n* **Memory management**: Kotlin assumes the existence of a Garbage Collector (provided by the Dalvik runtime in Android) and therefore memory management is transparent for the developer. On the other hand, Swift manages memory with a Reference Count approach (ARC) so you will need to think about memory ownership and retain cycles.\n\n* **System frameworks and libraries are very different**: When accessing system frameworks or libraries like networking, UI, etc. they both offer very different APIs so the resulting code will look pretty different.\n\nThe list of differences might look long, but trust me, the amount of features shared by both is much longer. I suggest you read [swift-is-like-kotlin](https://nilhcem.github.io/swift-is-like-kotlin/) for an extensive comparison of different features of the languages side to side to get the feeling about it and some of the syntactic differences.\n\n### MVVM + Rx + Coordinators\n\nOK, so we have some differences in the language and big differences in the system frameworks and libraries, especially in UI. But can we still reuse code? And can we increase code reuse somehow?\n\nThe answer is yes, we can still reuse the code, and yes, we can increase code reuse by properly **splitting responsibilities and isolating dependencies**. In other words, we need to carefully chose a proper app architecture, because a wrong choice will highly limit the amount of code reused.\n\nThere are multiple architectural patterns out there (MVC, MVP, MVVM, VIPER, FLUX,...), each of them with their own benefits/drawbacks and best usage scenarios. I am not going to explore or compare them here because that is out of the scope of this post, but let me quickly review the one that I chose for this sample project: MVVM + Rx + Coordinators.\n\nIn MVVM, the code is split in **Model**, **View** and **ViewModel**. Views include `UIViewController`/`Activities`/`Fragments`, while ViewModel is a new entity introduced to map the model into data that can be consumed by the View layer easily. The main benefit of this pattern is that the **Model and the ViewModel are completely agnostic from UI**, and it is the UI the one that will “listen” for changes in the ViewModel and not the other way around. Code in View layers get shorter, as they do not need to apply any logic but **just display what the ViewModel provides**. This is a good feature for our case because we mentioned that UI code will be pretty different for both apps, so then we can keep those differences isolated and as short as possible.\n\nThe addition of **[Rx](http://reactivex.io/)** gives us a very powerful framework to “listen” for the ViewModel changes, and at the same time keep consistency between platforms since there are [RxSwift](https://github.com/ReactiveX/RxSwift) and [RxJava](https://github.com/ReactiveX/RxJava) counterparts following the same conventions. They also have platform dependent additions ([RxCocoa](https://github.com/ReactiveX/RxSwift/tree/master/RxCocoa) and [RxAndroid](https://github.com/ReactiveX/RxAndroid)), but we will keep those **limited to the View layer**.\n\nFinally, I have added a **Coordinator layer**. This layer is sometimes also called Router, and it basically glues the different parts together and handles the navigation between them. The usage of coordinators helps us **building the dependency tree and isolating the navigation logic** out of the View layer.\n\n### Example code snippets:\n\nFor this post we will explore a very simple app consuming the [OpenTable API as exposed here](https://github.com/sosedoff/opentable). The app will just present a list of restaurants, add some pagination when scrolling to the end of the table, and open a simple restaurant detail. I should also mention that I kept the connector to the API in an external library, not dependent to Rx, in case we want to build a different app without Rx but reusing the OpenTable connector, but we could have added the Rx dependency there as well to simplify the callbacks.\n\nHere are some of the different parts side to side:\n\n##### RestaurantSearch\n\n```swift\n//RestaurantSearch.swift\npublic struct RestaurantSearch {\n public let totalResults: Int\n public let currentPage: Int\n public let resultsPerPage: Int\n public let restaurants: [Restaurant]\n}\n\nextension RestaurantSearch: Unboxable {\n public init(unboxer: Unboxer) {\n self.totalResults = unboxer.unbox(key: \"total_entries\")\n self.currentPage = unboxer.unbox(key: \"current_page\")\n self.resultsPerPage = unboxer.unbox(key: \"per_page\")\n self.restaurants = unboxer.unbox(key: \"restaurants\")\n }\n}\n```\n\n\n```kotlin\n//RestaurantSearch.kt\npublic data class RestaurantSearch(\n @JsonProperty(\"total_entries\") public val totalResults: Int,\n @JsonProperty(\"restaurants\") public val restaurants: Array,\n @JsonProperty(\"current_page\") public val currentPage: Int,\n @JsonProperty(\"per_page\") public val resultsPerPage: Int\n)\n```\n\nString similarity: **47.45%**\n\n`RestaurantSearch` is a data class containing a search response. You can see in this particular case that both have the **same external API, but a different internal implementation**. In the Swift case we are using [Unbox](https://github.com/johnsundell/unbox) for JSON mapping, while in Kotlin we use [Jackson](https://github.com/FasterXML/jackson). Here we can see the first issue that was commented above: library differences. The good news are that it is an implementation detail that will not affect how you use the object at all, and that you could probably find (or build) a different mapping library that looks in the same way (or at least much more similar) in both platforms.\n\n##### RestaurantService\n\n\n\n```swift\n//RestaurantService.swift\npublic class RestaurantService {\n let networkSession: URLSession\n let baseUrl: URL\n\n public init(urlSession: URLSession = URLSession.shared,\n baseUrl: URL = URL(string: \"http://opentable.herokuapp.com/api/\")!) {\n self.networkSession = urlSession\n self.baseUrl = baseUrl\n }\n\n public func findRestaurants(priceRange: Int? = nil,\n name: String? = nil,\n address: String? = nil,\n state: String? = nil,\n city: String? = nil,\n zip: String? = nil,\n country: String? = nil,\n page: Int = 1,\n pageSize: Int = 25) -> ServiceTask {\n\n var params = [RequestParameter]()\n params.append(RequestParameter(\"price\", priceRange))\n params.append(RequestParameter(\"name\", name))\n params.append(RequestParameter(\"address\", address))\n params.append(RequestParameter(\"state\", state))\n params.append(RequestParameter(\"city\", city))\n params.append(RequestParameter(\"zip\", zip))\n params.append(RequestParameter(\"country\", country))\n params.append(RequestParameter(\"page\", page))\n params.append(RequestParameter(\"per_page\", pageSize))\n\n return NetworkRequestServiceTask(\n networkSession: networkSession,\n baseUrl: baseUrl,\n endpoint: \"restaurants\",\n params: params)\n }\n\n public func findRestaurant(restaurantId: Int) -> ServiceTask {\n return NetworkRequestServiceTask(\n networkSession: networkSession,\n baseUrl: baseUrl,\n endpoint: \"restaurants/\\(restaurantId)\")\n }\n}\n```\n\n```kotlin\n//RestaurantService.kt\npublic class RestaurantService(\n val networkSession: HttpVolleySession = HttpVolleySession.getInstance(null, null),\n val baseUrl: String = \"http://opentable.herokuapp.com/api/\") {\n\n public fun findRestaurants(priceRange: Int? = null,\n name: String? = null,\n address: String? = null,\n state: String? = null,\n city: String? = null,\n zip: String? = null,\n country: String? = null,\n page: Int = 1,\n pageSize: Int = 25): ServiceTask {\n\n val params = arrayListOf()\n params.add(RequestParameter(\"price\", priceRange))\n params.add(RequestParameter(\"name\", name))\n params.add(RequestParameter(\"address\", address))\n params.add(RequestParameter(\"state\", state))\n params.add(RequestParameter(\"city\", city))\n params.add(RequestParameter(\"zip\", zip))\n params.add(RequestParameter(\"country\", country))\n params.add(RequestParameter(\"page\", page))\n params.add(RequestParameter(\"per_page\", pageSize))\n\n return NetworkRequestServiceTask(clazz = RestaurantSearch::class.java,\n networkSession = networkSession,\n baseUrl = baseUrl,\n endpoint = \"restaurants\",\n params = params)\n }\n\n public fun findRestaurant(restaurantId: Int): ServiceTask {\n return NetworkRequestServiceTask(clazz = Restaurant::class.java,\n networkSession = networkSession,\n baseUrl = baseUrl,\n endpoint = \"restaurants/${restaurantId}\")\n }\n}\n```\n\nString similarity: **87.62%**\n\n`RestaurantService` is a class that provides access to the OpenTable API. It provides a couple of methods to make search queries, and return a `ServiceTask` object that encapsulates the networking request and mapping. The resulting code as you can see is **almost identical**, except for the usage of a `UrlSession` vs a `VolleySession` and **minor syntactic differences**. Of course, once again the implementation details of the `NetworkRequestServiceTask` will be different in both platforms to deal with the networking libraries, but API wise they are the same and the `NetworkRequestServiceTask` and its dependencies can be reused across projects.\n\n##### RestaurantListState\n\n```swift\n//RestaurantListState.swift\nstruct RestaurantsListState {\n let restaurants: [Restaurant]\n let page: Int?\n let lastPage: Int?\n let totalResults: Int?\n let error: Error?\n let isLoading: Bool\n\n private init(restaurants:[Restaurant] = [], page: Int? = nil, lastPage: Int? = nil, totalResults: Int? = nil, error: Error? = nil, loading: Bool = false) {\n self.restaurants = restaurants\n self.page = page\n self.lastPage = lastPage\n self.totalResults = totalResults\n self.error = error\n self.isLoading = loading\n }\n\n static func notLoaded() -> Restaurants.List.State {\n return Restaurants.List.State()\n }\n\n static func loading(page: Int, previousState: Restaurants.List.State) -> Restaurants.List.State {\n return Restaurants.List.State(restaurants: previousState.restaurants, page: page, lastPage: previousState.lastPage, totalResults: previousState.totalResults, loading: true)\n }\n\n static func loaded(restaurants: [Restaurant], lastPage: Int, totalResults: Int) -> Restaurants.List.State {\n return Restaurants.List.State(restaurants: restaurants, lastPage: lastPage, totalResults: totalResults)\n }\n\n static func failedLoad(error: Error, previousState: Restaurants.List.State) -> Restaurants.List.State {\n return Restaurants.List.State(restaurants: previousState.restaurants, page: previousState.page, error: error)\n }\n\n var isLoaded: Bool { return lastPage != nil && totalResults != nil && isLoading == false }\n var isNotLoaded: Bool { return page == nil && lastPage == nil && isLoading == false }\n var isFailed: Bool { return error != nil }\n\n}\n```\n\n```kotlin\n//RestaurantListState.kt\ndata class RestaurantsListState private constructor(\n val restaurants: Array = arrayOf(),\n val page: Int? = null,\n val lastPage: Int? = null,\n val totalResults: Int? = null,\n val error: Error? = null,\n val isLoading: Boolean = false) {\n\n companion object {\n fun notLoaded(): RestaurantsListState {\n return RestaurantsListState()\n }\n fun loading(page: Int, previousState: RestaurantsListState): RestaurantsListState {\n return RestaurantsListState(restaurants = previousState.restaurants, page = page, lastPage = previousState.lastPage, totalResults = previousState.totalResults, isLoading = true)\n }\n fun loaded(restaurants: Array, lastPage: Int, totalResults: Int): RestaurantsListState {\n return RestaurantsListState(restaurants = restaurants, lastPage = lastPage, totalResults = totalResults)\n }\n fun failedLoad(error: Error, previousState: RestaurantsListState): RestaurantsListState {\n return RestaurantsListState(restaurants = previousState.restaurants, page = previousState.page, error = error)\n }\n }\n\n val isLoaded: Boolean get() = lastPage != null && totalResults != null && isLoading == false\n val isNotLoaded: Boolean get() = page == null && lastPage == null && isLoading == false\n val isFailed: Boolean get() = error != null\n\n}\n```\n\nString similarity: **77.33%**\n\nHere he have `RestaurantListState`, which is just a plain class holding state information used by the ViewModel. In this particular case, there are no dependencies to any other library or system framework, and therefore the **code is again very similar** except for the minor differences commented above (ex: `static` methods vs `companion` methods or `struct` vs `data class`)\n\n##### RestaurantListViewModel\n\n\n\n```swift\n//RestaurantListViewModel.swift\nclass RestaurantsListViewModel {\n private let restaurantService: RestaurantService\n private let state = BehaviorSubject(value: .notLoaded())\n\n var stateObservable: Observable { return state.asObservable() }\n var stateValue: Restaurants.List.State { return try! state.value() }\n\n init(restaurantService: RestaurantService) {\n self.restaurantService = restaurantService\n }\n\n func loadNextPage() {\n let nextPage = (stateValue.lastPage ?? 0) + 1\n loadPage(nextPage)\n }\n\n private func loadPage(_ page: Int) {\n guard !stateValue.isLoading else { return }\n\n state.onNext(.loading(page: page, previousState: stateValue))\n\n restaurantService.findRestaurants(country: \"US\", page: page)\n .onCompletion { [weak self] (result: RestaurantSearch?) in\n if let strongSelf = self {\n let restaurants = strongSelf.stateValue.restaurants\n strongSelf.state.onNext(.loaded(\n restaurants: restaurants + (result?.restaurants ?? []),\n lastPage: page,\n totalResults: result?.totalResults ?? restaurants.count))\n }\n }.onError { [weak self] (error) in\n if let strongSelf = self {\n strongSelf.state.onNext(.failedLoad(error: error, previousState: strongSelf.stateValue))\n }\n }.execute()\n }\n}\n```\n\n```kotlin\n //RestaurantListViewModel.kt\n class RestaurantsListViewModel(\n private val restaurantService: RestaurantService) {\n private val state = BehaviorSubject.create(RestaurantsListState.notLoaded())\n\n val stateObservable: Observable get() = state.asObservable()\n val stateValue: RestaurantsListState get() = state.value\n\n fun loadNextPage() {\n val nextPage = (stateValue.lastPage ?: 0) + 1\n loadPage(nextPage)\n }\n\n private fun loadPage(page: Int) {\n if (stateValue.isLoading) {\n return\n }\n\n state.onNext(RestaurantsListState.loading(page = page, previousState = stateValue))\n\n restaurantService.findRestaurants(country = \"US\", page = page)\n .onCompletion { result ->\n val restaurants = stateValue.restaurants\n this.state.onNext(RestaurantsListState.loaded(\n restaurants = restaurants + (result?.restaurants ?: arrayOf()),\n lastPage = page,\n totalResults = result?.totalResults ?: restaurants.size))\n }.onError { error ->\n this.state.onNext(RestaurantsListState.failedLoad(error = error, previousState = stateValue))\n }.execute()\n }\n }\n```\n\nString similarity: **77.25%**\n\nThis class corresponds to the ViewModel that will be used by the list of restaurants screen. As you can see, once again **code fully resembles to each other**, with the small difference of memory management and `guard` statement in the Swift case. Very interesting to note as well is that this is the first code snippet using Rx. You can see how they both share the same methods and objects, so the resulting code is equivalent in both platforms. Thanks Rx for keeping consistency!\n\n##### RestaurantsCoordinator\n\n```swift\n//RestaurantsCoordinator.swift\nclass RestaurantsCoordinator: BaseCoordinator {\n static var identifier = CoordinatorIdentifier(identifier: \"RestaurantsCoordinator\")\n private let restaurantService: RestaurantService\n\n init(parentCoordinator: Coordinator?, restaurantService: RestaurantService = RestaurantService()) {\n self.restaurantService = restaurantService\n super.init(parentCoordinator: parentCoordinator)\n }\n\n override func start() {\n let vm = Restaurants.List.ViewModel(restaurantService: restaurantService)\n let vc = Restaurants.List.ViewController.newController(coordinator: self, viewModel: vm)\n presentViewController(viewController: vc)\n }\n\n func openRestaurant(restaurant: Restaurant) {\n let vm = Restaurants.Detail.ViewModel(restaurantService: restaurantService, restaurant: restaurant)\n let vc = Restaurants.Detail.ViewController(coordinator: self, viewModel: vm)\n presentViewController(viewController: vc)\n }\n}\n\n```\n\n```kotlin\n//RestaurantsCoordinator.kt\nclass RestaurantsCoordinator(context: Context, parentCoordinator: Coordinator?, val restaurantService: RestaurantService = RestaurantService()): BaseCoordinator(context, parentCoordinator) {\n companion object {\n val identifier = CoordinatorIdentifier(identifier = \"RestaurantsCoordinator\")\n }\n\n override fun start() {\n val vm = RestaurantsListViewModel(restaurantService = restaurantService)\n val intent = RestaurantsListActivity.newIntent(coordinator = this, viewModel = vm)\n presentActivity(intent)\n }\n\n fun openRestaurant(restaurant: Restaurant) {\n val vm = RestaurantsDetailViewModel(restaurantService = restaurantService, restaurant = restaurant)\n val intent = RestaurantsDetailActivity.newIntent(coordinator = this, viewModel = vm)\n presentActivity(intent)\n }\n}\n```\n\nString similarity: **70.40%**\n\n`RestaurantsCoordinator` is the class responsible of navigation and coordination between the different parts in the MVVM. It basically instantiates new views, view models and services when needed, and present them in screen. Check it out because even if the navigation in both platforms is handled differently, **the resulting code is so similar that you can barely notice the differences** except for the constructors and statics.\n\n##### RestaurantsListView\n\n\n\n```kotlin\n//RestaurantsListViewController.swift\nclass RestaurantsListViewController: UIViewController {\n fileprivate var viewModel: Restaurants.List.ViewModel!\n fileprivate var coordinator: Restaurants.Coordinator!\n fileprivate let disposeBag = DisposeBag()\n @IBOutlet weak var tableView: UITableView!\n @IBOutlet weak var searchTitle: UILabel!\n\n static func newController(coordinator: Restaurants.Coordinator, viewModel: Restaurants.List.ViewModel) -> UIViewController {\n let vc = R.storyboard.restaurantsListViewController.instantiateInitialViewController()!\n vc.viewModel = viewModel\n vc.coordinator = coordinator\n return vc\n }\n\n override func viewDidLoad() {\n super.viewDidLoad()\n\n tableView.register(R.nib.restaurantTableViewCell)\n tableView.register(R.nib.loadingTableViewCell)\n tableView.register(R.nib.errorTableViewCell)\n\n viewModel.stateObservable.subscribe(onNext: { [unowned self] state in\n if let results = state.totalResults {\n self.searchTitle.text = \"Number of restaurants: \\(results)\"\n }\n else if state.isLoading {\n self.searchTitle.text = \"Loading restaurants\"\n }\n }).addDisposableTo(disposeBag)\n\n //Data\n cellDataObservable.bindTo(tableView.rx.items(dataSource: tableDataSource))\n .addDisposableTo(disposeBag)\n\n //Item selection\n tableView.rx.modelSelected(CellData.self).subscribe(onNext: { [unowned self] (data) in\n if let restaurant = data.restaurant {\n self.coordinator.openRestaurant(restaurant: restaurant)\n }\n }).addDisposableTo(disposeBag)\n\n //Page loading\n tableView.rx.willDisplayCell.filter { [unowned self] (cell, indexPath) -> Bool in\n indexPath.row == self.viewModel.stateValue.restaurants.count - 1\n }.subscribe(onNext: { [unowned self] (data) in\n self.viewModel.loadNextPage()\n }).addDisposableTo(disposeBag)\n }\n\n override func viewWillAppear(_ animated: Bool) {\n super.viewWillAppear(animated)\n if viewModel.stateValue.isNotLoaded || viewModel.stateValue.isFailed {\n viewModel.loadNextPage()\n }\n }\n}\n\n//MARK: Table view management\nextension Restaurants.List.ViewController {\n enum CellData {\n case restaurant(Restaurant)\n case loading\n case error(Error)\n\n var restaurant: Restaurant? {\n guard case .restaurant(let restaurant) = self else { return nil }\n return restaurant\n } \n }\n\n struct SectionOfData: SectionModelType {\n typealias Item = CellData\n var items: [Item]\n\n init(items: [Item]) {\n self.items = items\n self.identity = identity\n }\n init(original: SectionOfData, items: [Item]) {\n self = original\n self.items = items\n }\n }\n\n fileprivate var cellDataObservable: Observable<[SectionOfData]> {\n return viewModel.stateObservable.map { [weak self] (state) -> [SectionOfData] in\n let restaurants: [CellData] = state.restaurants.map { .restaurant($0) }\n var sections = [SectionOfData(items: restaurants)]\n if self?.viewModel.stateValue.isLoading ?? false {\n sections.append(SectionOfData(items: [.loading]))\n }\n else if let err = self?.viewModel.stateValue.error {\n sections.append(SectionOfData(items: [.error(err)]))\n }\n return sections\n }\n }\n\n fileprivate var tableDataSource: RxTableViewSectionedDataSource {\n let dataSource = RxTableViewSectionedDataSource()\n dataSource.configureCell = { ds, tv, ip, item in\n switch item {\n case .restaurant(let restaurant):\n let cell = tv.dequeueReusableCell(withIdentifier: R.nib.restaurantTableViewCell, for: ip)!\n cell.configure(restaurant: restaurant)\n return cell\n\n case .loading:\n let cell = tv.dequeueReusableCell(withIdentifier: R.nib.loadingTableViewCell, for: ip)!\n cell.configure(message: \"Loading restaurants\")\n return cell\n\n case .error(let err):\n let cell = tv.dequeueReusableCell(withIdentifier: R.nib.errorTableViewCell, for: ip)!\n cell.configure(error: err)\n return cell\n }\n }\n return dataSource\n }\n\n}\n```\n\n```kotlin\n//RestaurantsListActivity.kt\nclass RestaurantsListActivity : AppCompatActivity() {\n enum class Sections { restaurant, loading, error }\n\n lateinit var coordinator: RestaurantsCoordinator\n lateinit var viewModel: RestaurantsListViewModel\n\n companion object {\n fun newIntent(coordinator: RestaurantsCoordinator, viewModel: RestaurantsListViewModel, @LayoutRes layoutId: Int = R.layout.restaurants_list_activity): Intent {\n val intent = Intent(coordinator.context, RestaurantsListActivity::class.java)\n ActivityInjector.register(intent) { activity: RestaurantsListActivity ->\n activity.coordinator = coordinator\n activity.viewModel = viewModel\n activity.setContentView(layoutId)\n }\n return intent\n }\n }\n\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n ActivityInjector.inject(this)\n\n viewModel.stateObservable.subscribe {\n if (it.totalResults != null) {\n search_title.text = \"Number of restaurants: ${it.totalResults}\"\n }\n else if (it.isLoading) {\n search_title.text = \"Loading restaurants\"\n }\n }\n\n recyclerView.adapter = recyclerViewAdapter\n recyclerView.layoutManager = layoutManager\n\n //Item selection\n recyclerViewAdapter.modelSelected.subscribe { data ->\n val restaurant = data.restaurant\n if (restaurant != null) {\n this.coordinator.openRestaurant(restaurant = restaurant)\n }\n }\n\n //Page loading\n RxRecyclerView.scrollEvents(recyclerView).filter { event ->\n layoutManager.findLastVisibleItemPosition() == viewModel.stateValue.restaurants.size - 1\n }.subscribe {\n viewModel.loadNextPage()\n }\n }\n\n override fun onResume() {\n super.onResume()\n if (viewModel.stateValue.isNotLoaded || viewModel.stateValue.isFailed) {\n viewModel.loadNextPage()\n }\n }\n\n override fun onDestroy() {\n super.onDestroy()\n if (isFinishing) { //Only unregister when explicit finish happens\n ActivityInjector.unregister(intent)\n }\n }\n\n // List management\n data class CellData(val restaurant: Restaurant? = null, val loading: Boolean = false, val error: Error? = null)\n\n val cellDataObservable: Observable>> by lazy {\n viewModel.stateObservable.flatMap { state ->\n val restaurants = state.restaurants?.map { CellData(restaurant = it) } ?: listOf()\n val sections = arrayListOf(SectionModelType(restaurants, Sections.restaurant.ordinal))\n if (viewModel.stateValue.isLoading) {\n sections.add(SectionModelType(listOf(CellData(loading = true)), Sections.loading.ordinal))\n }\n else if (viewModel.stateValue.isFailed) {\n sections.add(SectionModelType(listOf(CellData(error = viewModel.stateValue.error)), Sections.error.ordinal))\n }\n Observable.just(sections.toList())\n }\n }\n\n val recyclerViewAdapter: RxRecyclerViewAdapter by lazy {\n RxRecyclerViewAdapter(cellDataObservable)\n .useLayoutId { type ->\n if (type == Sections.restaurant.ordinal) {\n R.layout.restaurant_cell_layout\n }\n else if (type == Sections.loading.ordinal) {\n R.layout.loading_cell_layout\n }\n else {\n R.layout.error_cell_layout\n }\n }\n .configureItem { view, data, position, type ->\n if (type == Sections.restaurant.ordinal) {\n val restaurant = data.restaurant\n if (restaurant != null) {\n view.pictureImageView.loadImage(restaurant)\n view.nameTextView.setText(restaurant.name)\n view.addressTextView.setText(restaurant.address)\n var price = \"\"\n kotlin.repeat(restaurant.price) {\n price = price + \"€\"\n }\n view.priceTextView.setText(price)\n }\n }\n else if (type == Sections.error.ordinal) {\n view.textView.setText(data.error?.message)\n }\n }\n }\n\n val layoutManager = LinearLayoutManager(this)\n\n}\n```\n\nString similarity: **52.27%**\n\nOK, so here is the big deal. So far, code was very similar and can be easily shared (with small editions) from one to the other platform. However, as we warned above, the UI code will be very different. How much? You can compare it by yourself...\n\nBasically, they **both share a common approach** in which they have a constructor receiving the dependencies (for a very simple Dependency Injection); a view creation method (`viewDidLoad` / `onCreate`) that basically subscribes to the ViewModel observables and configures the list; a view appear method (`viewWillAppear` / `onResume`) that will load new results; and a set of methods and types to deal with the information from the list, which by the way could have been moved partially to the ViewModel probably.\n\nAs you can see, **they are similar (especially conceptually) but not equal**, so all in all I would say that you could use one as a template for the other, but you will still need to write about half of the code, but judge it yourself. \n\nOf course, if you create your own wrappers around the UI components, you could actually achieve a much higher code reuse rate by exposing similar APIs, but you will need to develop them and they will introduce extra learning steps for new developers (like I did for networking in the `NetworkServiceTask`, use a similar API with different implementations)\n\nOff-topic: note how the usage of Kotlin extensions removed all of the `findViewById` so typical (and error prone) in Android UI classes, and in iOS the usage of [R.swift](https://github.com/mac-cain13/R.swift) is also cleaning up many of the hardcoded strings.\n\n##### Layout\n\nIn this case I am not copying the layout code because **it is completely different**. In iOS, I have used Interface Builder to set my views, while in Android it uses layout XMLs.\n\n### Conclusion\n\n**Swift and Kotlin are great languages**, both adding a lot of added value to their corresponding alternative for mobile apps (Objective-C / Java). They are **safer** thanks to a strict strongly typed system that includes nullability in it. They are both very **pleasant** to work with because of a impressive type inference compiler and a beautiful and modern syntax. They both have very **powerful features**, like extensions, immutability and functional programming additions that allow new and better patterns and constructions to emerge.\n\nHowever, **although very similar**, they are not identical. **They have a few differences intrinsic to the language and the SO/runtime** where they run that makes impossible to use the exact same code in both platforms. Nevertheless, if we structure our code with a good pattern and **separation of concerns**, we can certainly get very similar code in most of our classes, keeping the main differences when interacting with system APIs like UI or Networking isolated. \n\nWe have seen a few examples of different parts of the app using MVVM + Rx + Coordinators, and we can see how code resembles to each other in the example classes (between 50% to 90% code matching, not counting layout). In fact, it is so similar that I made most of one platform as a copy+paste+edit from the other one, **saving a lot of time and reducing bugs** as both will behave almost identically. An added benefit is that Kotlin developers will be able to read/write Swift with ease and vice versa, which helps **consolidating teams, practices and code across platforms**, but still writing **fully native and high quality apps** with small differences to **adapt to different user’s expectations** derived from the platform itself (which is a big difference with other cross platform solutions out there like [ReactNative](https://facebook.github.io/react-native/), [Xamarin](https://www.xamarin.com/) or [PhoneGap/Cordova](http://phonegap.com/))\n\nNote: String similarity calculated with [Tools4Noobs](https://www.tools4noobs.com/online_tools/string_similarity/)\n\n","author":"Angel G. Olloqui","date":"2016-10-18","type":"article","categories":["Kotlin","Swift"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"10 Kotlin Tutorials for Beginners: Dive Into Kotlin Programming","url":"http://petersommerhoff.com/dev/kotlin/kotlin-beginner-tutorial/","body":"\n\n# 10 Kotlin Tutorials for Beginners: Dive Into Kotlin Programming\n\nThere is a serious lack of Kotlin tutorials for beginners![The first Kotlin tutorial for beginners](http://petersommerhoff.com/wp-content/uploads/2016/02/kotlin-programming-course-300x169.png). You only find experienced Java developers hacking down Kotlin code in record time. Don’t get me wrong — those are really great for other experienced developers and I enjoy watching them. But for beginners, they are just voodoo code appearing on the screen like magic.\n\nKotlin is actually a great language to learn first, if only the necessary tutorials were out there. So I decided to create a course that even total beginners can follow. Check out the first 10 Kotlin tutorials below or [check out the whole course](https://www.udemy.com/kotlin-course/?couponCode=AMAZINGREADERS25) (it’s $25 with the 50% reader discount).\n\n## #1: A Brief Overview of Kotlin\n\nLearn where Kotlin comes from, the language concepts it incorporates, and _why you should learn it_.\n\n\n\n## #2: Try It Out in 30 Seconds\n\nThis is a quick video for those who cannot wait to dive into code. Learn how to use the [Kotlin online editor](http://try.kotlinlang.org/) to try out some of the language basics.\n\n\n\n## #3: Installing the JDK\n\nIf you already have the Java Development Kit (JDK) installed, you can happily skip this step. If not, just follow this video and use [this link](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) that is mentioned in the video.\n\n\n\n## #4: Installing IntelliJ\n\nIf you don’t already have IntelliJ, you should change that right away — I really learned to love this powerful IDE. This tutorial guides you through the download and installation process. And [here’s the link](http://www.jetbrains.com/idea/) mentioned in the video.\n\n\n\n## #5: Setting Up IntelliJ\n\nThis tutorial covers just the most basic layout settings: how you can adjust the theme and font in IntelliJ to your favorite style.\n\n\n\n## #6: Using Kotlin Interactively in The REPL\n\nThe Kotlin REPL allows us to use Kotlin interpreter-style, so that we can put in an expression (or any line of code) and see what Kotlin does with it. It’s great to try out some basic expressions and calculations.\n\n\n\n## #7: Variables\n\nIt’s time to learn about variables in Kotlin. This tutorial covers how to create and use variables of different types and the differences of the val and var keywords (to create immutable and mutable variables, respectively).\n\n\n\n## #8: Basic Types & Strings\n\nThis tutorial covers all the basic types in Kotlin including strings. In the video, I go through the differences between the different data types for storing integer values, floating point numbers, text and logical values.\n\n\n\n## #9: Nullable Variables\n\nKotlin gets rid of the worst enemy of all Java developers — the NullPointerException. In Kotlin, you can use nullable types to decide which variables can be set to null and which cannot. By default, a variable just cannot be assigned to null.\n\n\n\n## #10: Your First Standalone Application\n\nThis tutorial covers how you can create a main() function in Kotlin to define the entry-point to your applications. Once you have made it through this lecture, you’re ready to go and really dive into development with Kotlin.\n\n\n\n## Continue Learning...\n\nIf you’re as excited about Kotlin as I am, you can get my whole course on Udemy for $25 using [this coupon link](https://www.udemy.com/kotlin-course/?couponCode=AMAZINGREADERS25).\n\nInside the course, you’ll go from the basics to more advanced topics. These include:\n\n* Conditional expressions using _if_ and _when_\n* Loops using _for_ and _while_\n* Arrays and lists\n* Functions\n* Classes, objects, interfaces, inheritance and all you need to know about object-orientation\n* Functional programming in Kotlin\n* Several coding challenges and quizzes for you to test what you’ve learned\n\nThe course will be improved and extended based on student feedback and I’ll be there to help you personally whenever you get stuck. That way, there is no excuse for not learning Kotlin — even if you’re a total beginner.\n\n[Join the course now (50% discount for my readers)](https://www.udemy.com/kotlin-course/?couponCode=AMAZINGREADERS25)\n\n## Any Thoughts?\n\nWhat do you think about Kotlin? Is it “better than Java” or just yet another JVM language for you?\n\nWhat else do you want to learn about Kotlin? Let me know in the comments and I’ll respond to you personally.\n\n","author":"Peter Sommerhoff","date":"2016-02-02","type":"article","categories":["Kotlin","Videos"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Exploring the Kotlin Standard Library - Part 2","url":"http://jamie.mccrindle.org/2013/01/exploring-kotlin-standard-library-part-2.html","body":"\nIn [Part 1](http://jamie.mccrindle.org/2013/01/exploring-kotlin-standard-library-part-1.html) of this series, I went through the default Kotlin namespace. In Part 2 I'll be going over [kotlin.io](http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/kotlin/io/package-summary.html).\n\nMost of the public function in kotlin.io are overloaded versions of print and println, which all delegate to System.out.\n\nkotlin.io also introduces readLine for reading lines from stdin and the use method. The use method is a great example of a general purpose extension method. The signature illustrates how to create an extension method that will apply to every class that implements Closeable:\n\n```kotlin\npublic inline fun T.use(block: (T)-> R) : R\n```\n\nThe iterate method from the default namespace works very well with the readLine method. A function to count the number of lines from stdin would look as follows:\n\n```kotlin\nfun main(args: Array) = iterate{ readLine() }.count({ true })\n```\n\nThe following example uses the 'use' method to read the text from a reader while managing its lifecycle:\n\n```kotlin\n// gets the contents fo the reader and then closes it\nvar contents = reader.use { it.readText() }\n```\n\nThe use method will return whatever the closure returns (in this case, the contents of the reader as a String).\n\nkotlin.io extends java.io.File, java.io.InputStream, java.io.OutputStream, java.io.Reader, java.io.Writer, java.io.BufferedReader and java.net.URL.\n\nFor reading files or streams, the API docs distinguish between those methods that can be used on huge amounts of data and those that can't. Those that can't are the ones that wait for the entire file to be read before returning a result e.g. readLines, whereas the those that use a closure or iterator pull data lazily. The following calls should not be used with huge amounts of data\n\n* readBytes\n* readLines\n* readText\n\nThe following can be used for huge amounts of data:\n\n* copyTo\n* forEachBlock\n* forEachLine\n\nFor InputStreams, Readers and Writers, the caller is typically responsible for closing the various streams, the exception being the useLines method.\n\nThe Kotlin stdlib enhances with java.io.File with a number of useful methods: copyTo, forEachBlock, forEachLine, isDescendant, listFiles, readBytes, readLines, readText, reader, recurse, relativePath, writeBytes, writeText\n\nThe following is an example of copyTo being used:\n\n```kotlin\nFile(\"/tmp/from.txt\").copyTo(File(\"/tmp/to.txt\"))\n```\n\nNote the following:\n\n* copyTo only works on files (not directories)\n* copyTo will create the target directory\n* copyTo will overwrite the target file\n* if the source file can't be found a FileNotFoundException will be thrown\n* copyTo will block until the file is written\n\nAs an example, the forEachBlock method could be used to provide a version of copyTo that reports progress as the target file is written as follows:\n\n```kotlin\n/**\n * Copies a file and calls the closure with the current number of bytes read as each block is read\n * to indicate progress\n */\npublic fun File.copyToWithProgress(file: File, closure : (Long) -> Unit) {\n file.directory.mkdirs()\n val output = FileOutputStream(file)\n output.use{\n var length = 0.toLong()\n this.forEachBlock { bytes, size ->\n length += size\n output.write(bytes, 0, size)\n closure(length)\n }\n }\n}\n```\n\nHere are a few more examples of what can be done with kotlin.io\n\n```kotlin\n// forEachLine\n//\n// reads all the lines from a file and prints them out\nFile(\"/tmp/from.txt\").forEachLine { println(it) }\n\n// isDescendent\n//\n// Confirms that from.txt is a descendant of /tmp\nval isDescendent = File(\"/tmp/from.txt\").isDescendant(File(\"/tmp\"))\n\n// listFiles\n//\n// Lists all the subdirectories in /tmp\nval files = File(\"/tmp\").listFiles{ it.isDirectory() }\n\n// readBytes\n//\n// reads all the bytes from /tmp/from.bin\nval bytes = File(\"/tmp/from.bin\").readBytes()\n\n// readLines\n//\n// reads all the lines from /tmp/from.txt into a list\n// and then runs through each line in the list and prints it out\nval lines = File(\"/tmp/from.txt\").readLines()\nlines.forEach { println(it) }\n\n// readText\n//\n// reads all the text from /tmp/from.txt into a string\n// and then checks if it contains a multiline string\nval text = File(\"/tmp/from.txt\").readText()\nval found = text.contains(\"hello\\nworld\\n!\")\n\n// reader\n//\n// creates a reader and calls useLines on it\nval fileReader = File(\"/tmp/from.txt\").reader().useLines {\n // same as calling forEachLine\n}\n\n// recurse\n//\n// recurse through all the files in /tmp and print out their names\nFile(\"/tmp\").recurse { println(it.name) }\n\n// relativePath\n//\n// returns nested/directory/file.txt\nFile(\"/tmp\").relativePath(File(\"/tmp/nested/directory/file.txt\"))\n\n// writeBytes\n//\n// write Hello World as bytes to /tmp/helloworld.bin\nFile(\"/tmp/helloworld.bin\").writeBytes(\"Hello World!\".getBytes())\n\n// writeText\n//\n// write Hello World as bytes to /tmp/helloworld.txt\nFile(\"/tmp/helloworld.txt\").writeText(\"Hello World!\")\n```\n\n","author":"Jamie McCrindle","date":"2013-01-25","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.0 Released: Pragmatic Language for JVM and Android","url":"http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/","body":"\nThis is it. 1.0 is here!\n\nIt’s been a long and exciting road but we’ve finally reached the first big 1.0, and we’re celebrating the release by also presenting you with the new logo:\n\n![Kotlin logo](http://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/02/1_0_Banner.png?resize=640%2C320)\n\nSee discussions on [Reddit](https://www.reddit.com/r/programming/comments/45wcnd/kotlin_10_released_pragmatic_language_for_jvm_and/) and [Hacker News](https://news.ycombinator.com/item?id=11103087)\n\n## What is Kotlin?\n\nKotlin is a pragmatic programming language for JVM and Android that combines OO and functional features and is focused on **interoperability**, **safety**, **clarity** and **tooling** support.\n\nBeing a general-purpose language, Kotlin **works everywhere where Java works**: server-side applications, mobile applications (Android), desktop applications. It works with all major tools and services such as\n\n* IntelliJ IDEA, Android Studio and Eclipse\n* Maven, Gradle and Ant\n* Spring Boot (Kotlin support released today!)\n* GitHub, Slack and even Minecraft :)\n\nOne of the key focuses of Kotlin has been interoperability and seamless support for **mixed Java+Kotlin projects**, making adoption easier leading to less boilerplate code and more type-safety. Additionally, Kotlin has an **extensive standard library** that makes everyday tasks easy and smooth while keeping the bytecode footprint [low](http://www.methodscount.com/?lib=org.jetbrains.kotlin%3Akotlin-stdlib%3A1.0.0-rc-1036). Of course, **any Java library can be used in Kotlin**, too; and vice versa.
\n\n## What does pragmatic mean?\n\nUnderstanding one’s core values is crucial for any long-running project. If I were to choose one word to describe Kotlin’s design, it would be **pragmatism**. This is why, early on, we said that Kotlin is not so much about invention or research. We ended up inventing quite a few things, but this was never the point of the project. Of course we were building a **type system that prevents bugs**, and **abstraction mechanisms that facilitate code reuse**, as anybody in our position would. But our (pragmatic) way of doing it was through **focusing on use cases** to make the language a **good tool**.\n\nIn particular, this approach lead us immediately to the notion that **interoperability with existing code and infrastructure is crucial**. Re-writing the world the right way, all from scratch — who never wished to? I did, quite a few times :) And Kotlin would have been a whole lot easier to design and develop if not for the Java interop, Maven integration, Android compatibility! It would definitely be more elegant in many ways. But elegance, though highly appreciated, is not the primary goal here, **the primary goal is being useful**. And the less our users have to re-learn, re-invent, re-do from scratch, the more they can re-use, the better.\n\n— ***So, why doesn’t Kotlin have its own package manager, or its own build system?***\n— Because there’s already Maven and Gradle, and re-using their huge number of plugins is crucial for many projects.\n— ***Why did we invest a lot of time and effort into making JDK-compatible collection interfaces, when it was so much easier to just redesign collections from scratch?***\n— Because tons and tons of Java code work with JDK collections, and converting data on the boundary would be a pain.\n— ***Why does Kotlin support Java 6 byte code?***\n— Because many people are still running Java 6 (Android, most notably, but not only Android).\n\nFor us pragmatism is about **creating user experience**, not a language or a library alone. Many of the language design decisions were made under constraints like “Won’t this impede incremental compilation?”, “What if this increases APK method counts?”, “How will the IDE highlight this as-you-type?”, and many more like these. As a result, we are proud of our **tooling as well as the language**.\n\n## Is it mature enough and ready for production?\n\nYes. And it has been for quite some time. At JetBrains, we’ve not only been implementing the compiler and tooling but have also been using Kotlin **in real-life projects** on a rather extensive scale over the last two years. In addition to JetBrains, there are quite a few companies that have been using Kotlin **in production** for some time now.\n\nIn fact, one of the reasons it took us a long time to reach 1.0 was because we paid extra attention to validating our design decisions in practice. This was and is necessary, because moving forward the compiler will be **backwards compatible** and future versions of Kotlin must not break existing code. As such, whatever choices we’ve made we need to stick with them.\n\nReaching this milestone was something we couldn’t have done without the valuable **help of early adopters**. We want to thank each any every one of you for your bravery, energy and enthusiasm!\n\n## Who’s behind Kotlin?\n\nFirst and foremost, Kotlin is an Open Source language\n\n* Developed on [GitHub](https://github.com/JetBrains/kotlin) **under Apache 2.0 Open-Source license**;\n* With **over 100 contributors** to date.\n\nJetBrains is the main backer of Kotlin at the moment: we have invested a lot of effort into developing it and **we are committed to the project for the long run**. We wrote it out of our own need to use in our own products. And we’re happy to say that to date, **close to 10 JetBrains products**, which include IntelliJ IDEA, [JetBrains Rider](https://blog.jetbrains.com/dotnet/2016/01/13/project-rider-a-csharp-ide/), JetBrains Account & E-Shop, YouTrack as well as some of our smaller IDE’s and some internal projects are using Kotlin. So **it’s here to stay**!\n\nSince 2012 we kept Kotlin’s development very open: talking to the community all the time, gathering and addressing lots of feedback.\n\nMoving forward we are planning to set up a centralized venue for design proposals and discussions, to make the process even more visible and organized. Standardization efforts have not been started for Kotlin so far, but we realize that we’ll need to do it rather sooner than later.\n\nLanguage design and overall steering of the project is done by the team employed at JetBrains. We currently have **over 20 people working full time** on Kotlin, which also yet another testament to JetBrains’ commitment to Kotlin.\n\n## The numbers\n\nLet’s take a look at some numbers:\n\n* **11K+** people were using Kotlin last month and near **5K** last week alone;\n* **Hundreds** of [StackOverflow answers](http://stackoverflow.com/questions/tagged/kotlin);\n* **Two books**: [Kotlin in Action](https://www.manning.com/books/kotlin-in-action) and [Kotlin for Android Developers](https://leanpub.com/kotlin-for-android-developers);\n* **About 1400 people** on [Slack](http://kotlinlang.slack.com/) ([get an invite](http://kotlinslackin.herokuapp.com/));\n* **Over 500K** lines of Kotlin code in projects such as IntelliJ IDEA and Rider.\n\nTalking about lines of code, the number of these in open repositories on GitHub is **growing exponentially over time** (JetBrains’ projects excluded):\n\n\n![Kotlin GitHub Adoption](http://blog.jetbrains.com/kotlin/files/2016/02/KotlinAdoption.gif)\n\nAnd of course we have a growing list of **companies using Kotlin** including Prezi and Expedia. By the way, if you’re using Kotlin, make sure you send us a [Pull Request](https://github.com/JetBrains/kotlin-web-site/blob/master/_data/companies-using-kotlin.yml).\n\n## The upcoming roadmap\n\nAs of 1.0, we are committed to long-term **backward compatibility** of the language and its standard library (`kotlin-stdlib`):\n\n* **a newer compiler will work with older binaries** (but older compilers may not understand newer binaries, like javac 1.6 can’t read classes compiled by javac 1.8);\n* **older binaries will keep working with newer binaries at runtime** (newer code may require newer dependencies, though).\n\nThis applies to the JVM/Android support only. The JavaScript support remains experimental for now and will have its own release later on.\n\nAs for the plans, our nearest goals are (apart from bug fixes):\n\nConstant performance improvements for the Kotlin toolchain (this includes, for example, incremental compilation in Gradle, that is in the works now);\nJavaScript support (including cross-compilation into both JVM and JS where possible);\nSupport generating Java 8 byte code with optimized lambdas, etc (Java 6 will be actively supported as long as Android users need it).\nTooling updates and bug fixes will be released as incremental updates, i.e. 1.0.X. Bigger changes will first go though an Early Access Program (EAP) and then will be released as 1.1.\n\n## How to start\n\nThe easiest way to play with the language is through its **online mini-IDE**: [try.kotl.in](https://try.kotlinlang.org/), including [Koans](http://try.kotlinlang.org/koans) — a set of introductory problems which **guide you through the basics** of the language.\n\nTo use Kotlin on your machine (and Koans can be completed [offline](https://kotlinlang.org/docs/tutorials/koans.html) as well):\n\n* **IntelliJ IDEA** ([Ultimate or Community](https://www.jetbrains.com/idea/download/)): just create a Kotlin project or a Kotlin file in a Java project;\n* **Android Studio**: install the plugin through ***Plugin Manager***;\n* **Eclipse**: install the plugin through [Marketplace](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse).\n\nNOTE: If you are running an older version, you may need to update your Kotlin plugin to 1.0.\n\nTo get up to speed with concepts, language **docs and tutorials** are available from the [official web site](https://kotlinlang.org/). Great articles and presentations given by members of our community can be found in the [Digest of 2015](http://blog.jetbrains.com/kotlin/2016/01/kotlin-digest-2015/).\n\nIf you’re introducing Kotlin to your Java project, you can make use of the **Java-to-Kotlin converter** built into the IDE, helping migration easier class by class.\n\nLast but not least, make sure you join the discussions on our [Forum](https://devnet.jetbrains.com/community/kotlin) or [Slack](http://kotlinslackin.herokuapp.com/).\n\nOnce again, **we want to thank everyone**. We couldn’t have done this without the community.\n\nHave a nice Kotlin! **Now** :)\n\nP.S. See discussions on [Reddit](https://www.reddit.com/r/programming/comments/45wcnd/kotlin_10_released_pragmatic_language_for_jvm_and/) and [Hacker News](https://news.ycombinator.com/item?id=11103087)\n","author":"Andrey Breslav","date":"2016-02-15","type":"article","categories":["JetBrains","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Night London","url":"https://www.youtube.com/watch?list=PLoo7Ank5cc7FaemZS4sZC0oFnSbdJ-PiH&v=TMZD1GxAC8E","body":"\n[Announce](https://blog.jetbrains.com/kotlin/2016/09/kotlin-night-in-london/) | [Post in Kotlin Blog](https://blog.jetbrains.com/kotlin/2016/11/kotlin-night-in-london-recordings/)\n\n\n\n","author":"JetBrains","date":"2016-11-15","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Native","url":"https://medium.com/@octskyward/kotlin-native-310ffac94af2#.3oep6gxpa","body":"\n### Kotlin Native\n\nA frequent question about Kotlin is if/when it will support compilation to native binaries that run without a JVM. Usually this takes the form of a more technical question like, “will the Kotlin compiler get an LLVM backend?”\n\nI am not on the JetBrains team and I believe they’ve already made up their minds to do this, but I don’t personally think this feature would be the best way to solve the problems that are driving these questions.\n\nLuckily, there are better ways that can. Kotlin doesn’t need an LLVM backend: the wider JVM community is producing all the needed puzzle pieces already. Someone just has to put them together.\n\n### Why do people want native binaries?\n\nHere’s an entirely unscientific summary of the top reasons why people so often request a native backend for managed languages, based on conversations I’ve had over the years:\n\n1. They think the code would run faster or use less memory\n2. They want better startup time\n3. They think deploying programs that have only one file is simpler\n4. They want to avoid garbage collection\n5. They want to run on iOS, which forbids JIT compilers by policy\n6. They want better native-code interop\n\nThis list covers two of the three reasons cited by [the Scala Native website](http://www.scala-native.org/) for why it exists. The other reason is that Scala Native is extending the language to support C++ like constructs that are normally forbidden by the JVM, like forced stack allocation, but building a better C++ is already being handled by Rust. I suspect that trying to convert Scala or Kotlin into C++/Rust competitors wouldn’t go well.\n\nSometimes people think a ‘native’ version of a managed language would fix problems that have nothing to do with compiler technology, like [this guy](https://news.ycombinator.com/item?id=11226023) who believes it would change font rendering. I’ve seen ‘native’ become a mythical cure-all for any frustration or problem the user might have ... which isn’t surprising, given that most people have no experience with managed-to-native technologies.\n\n### A ‘Kotlin Native’ would make slower code\n\nIt is a common belief that code compiled by an ahead-of-time compiler must be faster or less memory hungry than just-in-time compiled code. I used to believe this too. It makes sense: C++ apps run fast, and C++ compilers are very slow. It stands to reason that the compilers are slow because they’re spending a lot of time optimising the code they’re producing. Surely, a compiler that can only grab a handful of spare cycles here and there whilst the app is running can never do such a good job?\n\nUnfortunately, performance is subtle and often unintuitive. C++ compilers are slow mostly due to the #include and generics model the language uses, not due to optimisations. And a team at Oracle is adding ahead of time compilation to HotSpot. They gave a tech talk about it last year called “[Java goes AOT](https://www.youtube.com/watch?v=Xybzyv8qbOc)”. Plain old AOT seems to give around 10%–20% slower code, depending on the kind of app (in the talk this is the difference between tiered and non-tiered). The reason is that virtual machines that support deoptimization, as the JVM does, can make speculative optimisations that aren’t always correct. Programs written in higher level languages benefit from this technique more, for instance Scala code benefits more than Java code does. The AOT compiler they’re using (Graal) isn’t weak or amateur: it’s competitive with GCC when compiling C code. It’s just that these advanced optimisations are really powerful.\n\nIt’s for this reason that the HotSpot AOT mode actually supports using a mix of AOT and JIT compiled code. The app can be compiled ahead of time so the interpreter isn’t used, but in a way that self-profiles. Then the JIT compiler is still invoked at runtime to recompile the hot spots, winning back most of the performance loss. You get a much less severe warmup period, whilst still obtaining the best peak performance.\n\nAndroid has learned the same lesson. The replacement for Dalvik that was introduced in Marshmallow (ART) started out as a pure AOT compiler. In Android N, it will start using a mix of AOT and JIT compilation.\n\nAdditionally, the shortest path to a Kotlin-specific native compiler backend would be LLVM. LLVM is primarily used to compile C and C++. Many optimisations that can really help high level managed languages like Kotlin simply don’t apply to C++, so LLVM doesn’t implement them at all. That’d result in an even bigger speed hit.\n\n> **Sidenote**: the .NET virtual machine does not have an interpreter nor does it support speculative optimisations. It’s really just a regular compiler that happens to run the first time a method is called. This is why Microsoft has tended to be more interested in AOT compilation than the Java space has been: they never exploited the potential of JIT compilation, so they have less to lose from abandoning it.\n\nWhat about other forms of bloat, like memory usage, binary size and startup time?\n\nEven those are complicated. Most of the memory usage of apps written in managed languages like Kotlin, Scala, Java, C# etc comes from their reliance on object identity, garbage collection, unicode strings and other things that native compilation doesn’t affect.\n\nWorse, native CPU code is a lot larger than JVM bytecode. Larger code bloats downloads and uses more RAM, lowering cache utilisation. An AOT compiled “Hello World” Java app doesn’t start any faster than the regular interpreted version because even though the interpreter runs far fewer instructions per second than the CPU can, each instruction does a lot more and takes much less space in memory. Runtime of a hello world app is only about 80 milliseconds anyway, which is a relevant cost only if you’re making tiny tools for a UNIX shell.\n\nAnd whilst hauling around a couple of JIT compilers and three garbage collectors adds bloat, that’s not inherent to using a virtual machine rather than compiling to native. It’s just that HotSpot is a one-size-fits-all program that is designed to run on everything from laptops to giant servers. You can make much smaller virtual machines if you’re willing to specialise.\n\n### Enter Avian\n\n> “Avian is a lightweight virtual machine and class library designed to provide a useful subset of Java’s features, suitable for building self-contained applications.”\n\nSo says [the website](https://readytalk.github.io/avian/). They aren’t joking. The example app demos use of the native UI toolkit on Windows, MacOS X or Linux. It’s not a trivial Hello World app at all, yet it’s a standalone self-contained binary that clocks in at only one megabyte. In contrast, “Hello World” in Go generates a binary that is 1.1mb in size, despite doing much less.\n\nAvian can get these tiny sizes because it’s fully focused on doing so: it implements optimisations and features the standard HotSpot JVM lacks, like the use of LZMA compression and ProGuard to strip the standard libraries. Yet it still provides a garbage collector and a JIT compiler.\n\nFor people who want to use Kotlin to write small, self contained command line apps of the kind Go is sometimes used for, a much simpler and better solution than an LLVM backend would be to make a fully integrated Avian/Kotlin combination. Avian is hard to use right now — you’re expected to be familiar with native-world tools like GCC and make. Making a one-click JetBrains style GUI would yield programs that _look_ to the user like they were AOT compiled: they’re single executables that only require the base OS. And using SWT you can build GUIs that look native on every platform because under the hood they _are_ native. But you wouldn’t need to abandon the benefits of JIT compilation or garbage collection.\n\n### Losing garbage collection\n\nSometimes the people requesting a native backend want it because they want to avoid GC, and associate “native” with “not garbage collected”. There is no connection between these things: you can have garbage collected C++ and you can do manual memory management in Java (and some high performance libraries do).\n\nThe problem with extensively mixing techniques is that it forks the language. A library that assumes garbage collection cannot be used without a collector and likewise, a library that expects manual management becomes a lot harder to use from code that expects a GC. You’d have to introduce smart pointers and other C++ like constructs to the language to make it really convenient.\n\nI wouldn’t like to see Kotlin splinter into two different languages, Kotlin-GC and Kotlin-Manual. That would hurt the community and ecosystem for questionable benefits.\n\nAnd the benefits _are_ questionable. Many devs who think they can’t tolerate GC are basing their opinions on old/crappy GCs in mobile phones or (worse) web browsers. This impression is heightened by the fact that some well known garbage collected apps are written by people who just don’t seem to care about performance at all, like Minecraft or Eclipse, leading people to blame GC for what is in reality just badly written code. But there are counterexamples that show it doesn’t have to be this way: Unreal Engine is written in C++ and has used a core garbage collected game heap since version 3. It powers many of the worlds AAA titles. They can hit 60 frames per second and they are using a very basic GC. Tim Sweeney’s secret is that he cares about performance and productivity simultaneously. If they can do it, so can you.\n\n### iOS and native code interop\n\nThe final reasons people want a native compiler backend are iOS support and to make native code interop easier.\n\niOS is a good reason. That platform bans JIT compilers because it helps Apple enforce their incredibly rigid policies. But doing a native backend at the language level is the wrong approach. RoboVM is a project that built a JVM bytecode to ARM AOT compiler, and although RoboVM is now a dead project due to being acquired by Microsoft, old versions of its code are still available under an open source license. It works for any JVM language and doesn’t really suffer from this generality: a Scala or Kotlin specific ARM compiler wouldn’t do much different.\n\nBut that’s probably not the long term direction the JVM platform will go in for iOS. As HotSpot itself is getting support for AOT compilation, and HotSpot has an ARM backend too, and there’s an official OpenJDK mobile project that’s already made an iOS (interpreter only) mobile version, it would make sense for them to plug these things together and end up with a mode in which HotSpot can generate AOT iOS binaries too. I wouldn’t be surprised to see something like this announced between Java 9 and 10.\n\nThe final reason is native code interop. If you compile to native, so the reasoning goes, it’ll be easier to use C/C++ libraries like the ones your operating system provides.\n\nBut the existence of projects like JNA seem to disprove this — you can have convenient interop without generating native code yourself. And there are some exciting techniques for working with native libraries coming up:\n\n* The OpenJDK Panama project is adding support for things like inline assembly, pointers and struct layouts directly to Java and HotSpot. Yes, if you check out the Panama branch of the hotspot repository you can actually define assembly snippets in Java and they’ll be inlined directly into usage sites, just like an __asm__ block in C would. Panama also provides a clang-based tool that parses C/C++ headers and auto generates the equivalent Java declarations. All this should be automatically available to Kotlin and Scala users too.\n* The Graal/Truffle research projects are creating [Sulong](http://github.com/graalvm/sulong/), which is a way to JIT compile LLVM bitcode on top of the JVM. There is a simple C API that exists when code is run on top of Sulong that allows for near zero-overhead interop with managed code.\n\n### Conclusion\n\nKotlin doesn’t need an LLVM backend, and by extension I believe neither does Scala. Creating such a thing would be a huge and ongoing drain of manpower, take a long time, and end up duplicating work already being done elsewhere in the JVM ecosystem ... very likely with worse results.\n\nInstead, I think the right direction for the community to go is:\n\n1. Building a simple IntelliJ plugin that uses Avian to spit out tiny, self contained binaries, for when weight is more important than features. This would present some strong competition to Go in the command line tools space.\n2. Using the AOT mode being added to HotSpot to eliminate warmup times and (hopefully) support iOS, for times when AOT compilation really is the only solution.\n3. Waiting for JVM upgrades to reduce memory usage, support better native interop and so on. Don’t try to duplicate these efforts at the language level.\n4. Educating the developer community about how to write high performance garbage collected apps _outside_ of the server context.\n\nThis approach isn’t flawless: the AOT mode being added to HotSpot is planned to be a commercial feature, and big upgrades like Panama are long term projects. But adding an LLVM backend to the Kotlin or Scala compilers would be a long term project too, it’d mean sacrificing other features that might be more useful, and it would likely never close the performance gap.\n\nAs always in engineering, there are no solutions — only trade offs. I’d rather have more features in the core Kotlin language/tooling than a native backend, and let other teams tackle the varying challenges involved.\n\n","author":"Mike Hearn","date":"2016-06-17","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Java vs. Kotlin: Should You Be Using Kotlin for Android Development?","url":"https://code.tutsplus.com/articles/java-vs-kotlin-should-you-be-using-kotlin-for-android-development--cms-27846","body":"","author":"Jessica Thornsby","date":"2016-12-12","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Ubuntu Make 16.03 Released With Eclipse JEE And IntelliJ IDEA EAP Support, More","url":"http://www.webupd8.org/2016/03/ubuntu-make-1603-released-with-eclipse.html","body":"\n[Ubuntu Make](https://github.com/ubuntu/ubuntu-make) is a command line tool created by Canonical, which allows installing various development tools on Ubuntu. It can be used to install Android Studio, Unity3D, IntelliJ IDEA, Firefox Development Edition, Node.js and much more.\n\n**Ubuntu Make 16.03, released today, adds support for [Eclipse JEE](http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/mars2) and [IntelliJ IDEA EAP](https://www.jetbrains.com/support/eap/), as well as for the [Kotlin compiler](https://kotlinlang.org/), along with various fixes, such as:**\n\n* fix Unity3D on lts mesa;\n* fix VSCode license page due to server changes;\n* fix Android-NDK not working due to server changes (download is now for 64bit only);\n* fix Clang support due to server changes;\n* fix Intellij .desktop file.\n\nA complete changelog can be found [HERE](https://github.com/ubuntu/ubuntu-make/blob/master/debian/changelog).\n\n![Ubuntu Make Eclipse Java EE IDE](https://2.bp.blogspot.com/-IxqVQB8bEqM/Vvu4uaN9s4I/AAAAAAAAXeY/LC8Uj6BECD8_GBY0DIDpho0-BxlUVDFVA/s1600/ubuntumake-eclipse-jee-ide.png)\n\nTo install the the newly added Eclipse JEE in Ubuntu using the latest Ubuntu Make (after installing Ubuntu Make, obviously), use the following command:\n\n`umake ide eclipse-jee`\n\nFor IntelliJ IDEA EAP, use:\n\n`umake ide idea --eap`\n\nTo install the Kotlin language compiler, use:\n\n`umake kotlin kotlin-lang`\n\nIf you want to remove any package installed using Ubuntu Make, simply append \"--remove\" to the command you used to install it. For example, to remove eclipse-jee, you would use:\n\n`umake ide eclipse-jee --remove`\n\nTo see all Ubuntu Make can do, type:\n\n```bash\numake --help\n# and\nman umake\n```\n\n## Install Ubuntu Make\n\nUbuntu Make is available in the official Ubuntu repositories (starting with Ubuntu 15.04) however, it's not the latest version, as you can see [HERE](https://launchpad.net/ubuntu/+source/ubuntu-make) (though the latest Ubuntu Mate 16.03 will probably make it into Ubuntu 16.04 Xenial Xerus).\n\n**To install the latest Ubuntu Make, in Ubuntu (16.04, 15.10 and 14.04), Linux Mint 17.x and derivatives, you can use its PPA. Add the PPA and install Ubuntu Make by using the following commands:**\n\n```bash\nsudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make\nsudo apt-get update\nsudo apt-get install ubuntu-make\n```\n\nIf you want to help with the Ubuntu Make development, report bugs, etc., check out its [GitHub page](https://github.com/ubuntu/ubuntu-make).\n\n_via [didrocks](http://blog.didrocks.fr/post/Ubuntu-Make-16.03-features-Eclipse-JEE%2C-Intellij-EAP%2C-Kotlin-and-a-bunch-of-fixes!2)_\n\n","author":"Alin Andrei","date":"2016-03-30","type":"article","categories":["Kotlin","Ubuntu"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Why Kotlin is my next programming language","url":"https://medium.com/@octskyward/why-kotlin-is-my-next-programming-language-c25c001e26e3","body":"\n\n![](https://d262ilb51hltx0.cloudfront.net/max/1600/1*YnF7hY2ymS54iTNLuxVT8A.jpeg)\n_A lighthouse on Kotlin Island, Russia_\n\n## An ode to the language you’ve never heard of\n\n[Kotlin](http://kotlinlang.org/) is a new programming language from [JetBrains](http://jetbrains.com%5C), the maker of the world’s best IDEs. After much searching, I have settled on it as the programming language I will probably use for the next 5–10 years or so.\n\nI like Kotlin a lot and think it will be a very successful project. Someone who saw me using it in my open source work asked me to write about it, so in this article I’ll explain why I think Kotlin is good. Then I will discuss some of the problems and hiccups you may encounter if you start using it today. Finally, I’ll argue that now Kotlin is on the scene you should consider using the JVM if you aren’t already (e.g. because you use Go or Node).\n\n### Why Kotlin is good\n\nAt first this article may seem strange: normally language advocacy articles start by listing all the cool features the new language has. This article does not; we will get to them later.\n\nI am going to start by telling you about other things, because [a 2013 study showed that language features matter little compared to ecosystem issues](http://sns.cs.princeton.edu/docs/asr-oopsla13.pdf) when developers evaluate programming languages. That tallies with my own experience, so, here we go:\n\n**Kotlin compiles to JVM bytecode or JavaScript**. It is not a language you will write a kernel in. It is of greatest interest to people who work with Java today, although it could appeal to _all_ programmers who use a garbage collected runtime, including people who currently use Scala, Go, Python, Ruby and JavaScript.\n\n**Kotlin comes from industry**, not academia. It solves problems faced by working programmers today. As an example, the type system helps you avoid null pointer exceptions.\n\n**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. You can convert an existing Java project one file at a time and everything will still compile, even for complex programs that run to millions of lines of code. This is how I am adopting Kotlin and I expect it to be how most developers do.\n\nAs an obvious implication of the above, **Kotlin programs can use all existing Java frameworks and libraries**, even advanced frameworks that rely on annotation processing. The interop is seamless and does not require wrappers or adapter layers. It integrates with Maven, Gradle and other build systems.\n\nIt is approachable and **it can be learned in a few hours** by simply reading the language reference. The syntax is lean and intuitive. Kotlin looks a lot like Scala, but is simpler. The language balances terseness and readability well.\n\n**It enforces no particular philosophy of programming**, such as overly functional or OOP styling.\n\nIt **imposes no runtime overhead.** The standard library is small and tight: it consists mostly of focused extensions to the Java standard library. Heavy use of compile-time inlining means functional constructs like pipelines of map/filter/reduce compile similarly to an imperative version of the same code.\n\nCombined with the appearance of frameworks like [Anko](https://github.com/JetBrains/anko) and [Kovenant](http://kovenant.komponents.nl/android/features/), this resource lightness means **Kotlin is starting to become popular with Android developers**. If you’re working on Android, you will soon be in good company. You can read [a report written by a developer at Square](https://docs.google.com/document/d/1ReS3ep-hjxWA8kZi0YqDbEhCqTt29hG8P44aA9W0DM8/edit?hl=en&forcehl=1) on their experience with Kotlin and Android.\n\nKotlin allows you to keep using your productivity enhancing tools. If you use IntelliJ, **IDE interop is entirely seamless**: code can be refactored, searched, navigated and auto completed as if the Kotlin code was Java and vice-versa. There is full support for debugging, unit testing, profiling and so on.\n\nBeyond Android, I think **Kotlin is highly suitable for enterprise Java shops**. If you spend all day working on big Java codebases at even bigger companies, you should investigate Kotlin because:\n\n* It has **strong commercial support from an established company**. JetBrains is committed to the project, has a large and highly competent team working on it, has a stable business model and is even converting parts of their own flagship product to use it. Kotlin is unlikely to be abandoned any time soon.\n* **Adopting Kotlin is low risk**: it can be trialled in a small part of your code base by one or two enthusiastic team members without disrupting the rest of your project: Kotlin classes export a Java API that looks identical to that of regular Java code.\n* Because Kotlin focuses on readable syntax, **code reviews are not a problem**: they can still be done by team members who aren’t familiar with the language.\n* **It targets** **Java 6**, so you can use it even if your deployment makes upgrading to a newer JVM difficult.\n\nEarlier this year I presented Kotlin to a team of Java and .NET architects at Swiss Re, a large reinsurance company. I started by defining a simple Java class with a few fields, toString, equals, hashCode etc. It was about 50 lines of code. By the time we had finished converting it to Kotlin (mostly automatically), it had shrunk to just one line of code. I then demoed other time saving features. They were enthusiastic and saw it as a potentially strong competitor to C# for their own projects.\n\nI think Kotlin hits the sweet spot for enterprise Java devs, so even though Kotlin is free I expect JetBrains to make a killing from increased sales of the commercial version of their IDE. This will incentivise them to keep improving it according to the wishes of their customers.\n\nContrast this with many other language developers who are subsidised by unrelated products, meaning they have little reason to respond to the demands of their users when those demands conflict with pre-held ideologies.\n\n","author":"Mike Hearn","date":"2015-07-06","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Why Kotlin is the next big thing for Java developers","url":"https://jaxenter.com/kotlin-next-big-thing-java-developers-129319.html","body":"\n> Kotlin already looks like a tool that is going to improve productivity significantly. We anticipate that it is definitely going to reduce the pain points faced by Java developers. Here is why we think Kotlin will be the next big thing for the Java community.\n\nKotlin is a high-performance language, it runs on the JVM and uses existing Java libraries and tools. Plus, Java can also interact with Kotlin components seamlessly. The primary goal of Kotlin is to make it useful for practical, real-life projects; one can easily learn it compared to other JVM-based languages (such as Scala). Since Java has a deep interoperability with Kotlin, Java developers may be more attracted to learn and test it.\n\nKotlin also has a strong commercial support and stable business model. From a developer’s perspective, Kotlin is very promising and gets better [with every release](https://jaxenter.com/kotlin-1-0-4-is-here-129315.html). So we can safely predict that Kotlin will be the next big thing for the Java community.\n\n## Is Kotlin a good fit for Java developers?\n\nAll that JetBrains wanted was to provide a useful language that solves existing problems. Kotlin has the following objectives which will help users solve or avoid existing issues in Java and ultimately perform better.\n\n* Provides an intuitive language that can infer from codes written by developers and do a lot of work on behalf of developers.\n* Improves productivity by reducing the effort needed to write code. For example, a 50 lines (approx.) code written in Java can be reduced to 2/3 (approx.) lines in Kotlin.\n* Prevents null pointer exceptions.\n* Provides quick code compilation.\n* Reduces learning time for developers by providing documentation and support.\n* Kotlin code syntax is easy to understand, so the code review is simple even for a newcomer.\n* Runtime overhead is also low as the standard library is small and compact.\n\nApart from the above-mentioned advantages, Kotlin also provides easy code conversion between Java and Kotlin, easy IDE integration, full debugging, refactoring and profiling etc. Therefore, we anticipate that Kotlin is definitely going to reduce the pain points faced by the Java developers.\n\n## The Kotlin features Java developers should love\n\nThese are the features Java developers should love:\n\n**No more null pointer exceptions**\n\nThis is probably the most important feature. The null pointer exception is one of the most dreaded, unsolved issues developers face. Kotlin’s type system does not compile code that assigns or returns null. See the example below.\n\n```kotlin\nval name: String = null // tries to assign null, won't compile\nstephen getName() : String = null // tries to return null, won't compile\n```\n\nSince every method call on a nullable type can potentially cause a null pointer exception, the Kotlin compiler forces the developer to use the Elvis operator whenever the call result is assigned to a non-null type.\n\n**Less code**\n\nKotlin compiler can infer or understand from the code written by a developer and can develop or write the remaining code. Java requires the developer to explicitly write everything which consumes a lot of time and effort. Kotlin saves effort and time and improves productivity.\n\nFor example, the Kotlin compiler can infer types in variable declarations, as well as compiler-generated getters/setters/equals/hashCode. On the other hand, the Java compiler does not infer as much and requires the developer to explicitly write code.\n\n**Easy to learn and use **\n\nSince there is nothing revolutionary about Kotlin, any software developer can learn and use it, especially the Java and Scala developers. The main reason is that Kotlin is dependent on Java in many ways and extensively uses the Java library.\n\nAlso, Kotlin was inspired by Scala and according to many people, it looks a lot like Scala. The code uses the JVM and the Javac, the primary Java compiler. The learning curve for Java developers is not steep and they can leverage the Kotlin documentation and get started quickly with coding.\n\n**Backward compatible**\n\nKotlin offers backward compatibility for Java versions 6 and 7. It states on its blog that over the next few releases, it is going to speed up development workflow, reduce the size of the runtime library and provide more tooling support. Kotlin introduced a feature known as incremental [compilation](https://jaxenter.com/kotlin-1-0-4-is-here-129315.html) in its Gradle build plug-in. This enables Kotlin to compile and build only the changes in the code and not the whole code over. This is going to save a lot of time.\n\n**IDE interoperability**\n\nKotlin has a lot of supports for enhancing productivity. It is highly interoperable with the IDEs, so refactoring, debugging, searching, unit testing are very easy to perform.\n\nMaybe a Java developer can convert part of his Java code into Kotlin and see how it performs. No matter what path you choose, Kotlin is definitely going to make a good impression on you.\n\n## Conclusion\n\nKotlin already looks like a tool that is going to improve productivity significantly. Many developers are positive about Kotlin enabling them to achieve a breakthrough in their productivity.\n\nThere are many online discussions which claim that Kotlin solves many Java pain points without really reinventing how coding should be done. What are the challenges ahead? First, it needs to impress companies like Google, which is a huge Java user and has been working on other alternatives to Java.\n\nIt will be interesting to watch how Kotlin accomplishes its plans and how it faces forthcoming challenges.\n\n","author":"Nitin Y","date":"2016-09-23","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin for Java developers","url":"https://www.youtube.com/watch?v=vmjfIRsawlg","body":"\n\n\n","author":"Hadi Hariri","date":"2014-12-11","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin & Android: A Brass Tacks Experiment, Part 6","url":"https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-6-49fea0ed3a7#.53axmkcxt","body":"\n![](https://d262ilb51hltx0.cloudfront.net/max/1600/1*UN-S8ELMC2kpHf4tJKfbLQ.png)\n\n_Disclaimer: I am a Google employee, but the views expressed in this article are not those of my employer._\n\n### Kotlin & Android: A Brass Tacks Experiment, Part 6\n\nAlright! We’re nearing the end of this series about experimenting with Kotlin to make view creation easier during Android app development. (Please [jump back to the beginning](https://medium.com/p/kotlin-android-a-brass-tacks-experiment-part-1-3e5028491bcc) if you landed here prematurely.) So far we’ve learned a bunch of features of the Kotlin® language that help implement the type-safe builder pattern, including:\n\n* Lambda with receiver & reified types ([part 2](https://medium.com/p/kotlin-android-a-brass-tacks-experiment-part-2-c67661cfdf5f))\n* Extension functions ([part 4](https://medium.com/p/kotlin-android-a-brass-tacks-experiment-part-4-4b7b501fa457))\n* Extension properties ([part 5](https://medium.com/p/kotlin-android-a-brass-tacks-experiment-part-5-bd79eb9c85d4))\n\nThese have all been instrumental in creating a “domain specific language” for expressing the programmatic creation of view hierarchies in a declarative fashion. For example, using all these techniques combined, we can write this to create two TextViews stacked on top of each other with some padding:\n\n```kotlin\nv {\n layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)\n orientation = VERTICAL\n padLeft = dp_i(16f)\n\n v {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n text = \"Hello\"\n }\n v {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n text = \"World\"\n }\n}\n```\n\nThis is pretty good on its own, and it definitely beats writing out all these view creations and associations traditionally. Now, to wrap up the coding part of this experiment, let’s do a couple more things to tighten up the syntax _even more!_\n\n**How do we assign values to specialized layout parameter properties?**\n\nIt’s not immediately evident from the code above, but there is a problem if you want to assign some attributes of the layout parameters specific to LinearLayout. Up until now we have only specified the height and width of a view using the [LinearLayout.LayoutParams](http://developer.android.com/reference/android/widget/LinearLayout.LayoutParams.html) class constructor, and assigned that new object to the layoutParams synthetic property of a view. But what if we also wanted to assign values to the “gravity” property of the layout parameters? It might make sense to try it like this:\n\n```kotlin\nlayoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\nlayoutParams.gravity = Gravity.CENTER // oops, compiler says no\n```\n\nBut the compiler won’t allow that because the layoutParams property of View is of type ViewGroup.LayoutParams, the superclass of all other LayoutParams. In order to use layoutParams as a LinearLayout.LayoutParams, it will need to be downcast.\n\nInstead of casting and assigning to another value as you would in the Java® language, we can use a Kotlin stdlib function called “[with](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/with.html)” to make it easier to deal with layoutParams. The “with” function takes an object parameter along with lambda with receiver and executes that lambda against the given object. This description may not sound interesting, but it allows a syntax like this:\n\n```kotlin\nv {\n with(layoutParams as LinearLayout.LayoutParams) {\n width = WRAP_CONTENT\n height = WRAP_CONTENT\n gravity = CENTER\n }\n text = \"Hello\"\n}\n```\n\nNotice how we’re able to simultaneously cast layoutParams to LinearLayout.LayoutParams, then use that as the receiver inside the lambda for abbreviated access to its properties.\n\nAnother subtle thing to be aware of here is that an Android view container will automatically create and assign a correctly typed layout parameter object to layoutParams when a child view is added to it. In our case, adding a TextView child to a LinearLayout will _automatically_ create and assign a LinearLayout.LayoutParams to the TextView’s layoutParams property. This means we don’t actually need to create a new LayoutParams object — we can just access the one that’s already provided by the parent LinearLayout. Please remember that this only happens when adding a child view to a parent ViewGroup. The outermost ViewGroup will not have layout parameters assigned automatically because it’s not yet attached to its own parent!\n\nAll that said, this is not exactly the _most_ desirable syntax for layout parameters, but it’s the most straightforward way I could find to specify specialized layout parameters inside the lambdas we have for creating views.\n\n**And now, for my last trick, I’ll make the “v” functions disappear!**\n\nThe “v” functions we’ve been using so far are pretty convenient, but what if we want to further shortcut their syntax? It would be even more convenient to take the layout from above and pattern it like this:\n\n```kotlin\nlinearLayout {\n textView {\n // properties...\n }\n textView {\n // properties...\n }\n}\n```\n\nThis looks even more natural, and makes for easy reading. It also looks very similar to the Android Gradle configuration language. The trick to getting a syntax like this is to effectively create a sort of alias for each type of view we want to use. So, to create a structure like above, we need a function called “linearLayout” that works like “v” and a function called “textView” that works like “v”. Kotlin makes this pretty easy to set up:\n\n```kotlin\nfun ViewGroup.linearLayout(init: LinearLayout.() -> Unit) = v(init)\nfun Context.linearLayout(init: LinearLayout.() -> Unit) = v(init)\n\nfun ViewGroup.textView(init: TextView.() -> Unit) = v(init)\nfun Context.textView(init: TextView.() -> Unit) = v(init)\n```\n\nHere, I defined two functions for each type of view in order to account for the different v functions that could be invoked, depending on the starting point of a Context or a ViewGroup parent. The Kotlin language feature that makes these declarations possible is called _single expression function_. This is a special syntax for functions that allows you to:\n\n1. Omit the usual curly braces for the function body.\n2. Infer the return type based on the return type of the expression.\n3. Omit the return keyword.\n\nNow, let’s use these convenience functions to recreate the view hierarchy from the beginning of this article:\n\n```kotlin\nlinearLayout {\n layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)\n orientation = VERTICAL\n padLeft = dp_i(16f)\n\n textView {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n text = \"Hello\"\n }\n textView {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n text = \"World\"\n }\n}\n```\n\nWow, we’ve come a long way since our humble beginnings in part 2! (As long as you’re willing to define alias functions for each type of view you want to build.)\n\n**But the novelty of this technique is not all that novel after all!**\n\nSome readers of this series have pointed out that this method using the type-safe builder pattern for building view hierarchies is really close to that of a project called [Anko](https://github.com/Kotlin/anko). I actually set out on this series without having any knowledge of it, and it wasn’t until I was finished with the first two parts of this series that one of my colleagues pointed this out to me. Anko provides a more comprehensive solution for building views than what I’ve been experimenting with here. Even after seeing it, I was still pretty interested in going through the process of discovering Kotlin language features and how they could be applied to Android development. If you’ve been following this series, I hope you’ve also enjoyed discovering these things!\n\n**So, are we really any better off with this technique?**\n\nYou might be wondering now if it’s better in general to create your Android views programmatically like this in Kotlin than the traditional XML layout resources. Up till now, it certainly seems like a big win to use Kotlin in this way. So, for the next part in this series, I’ll compare the two techniques with each other to see how they compare to each other. Also, I’ll provide a sample project that you can use to easily compare equivalent implementations.\n\nDon’t forget that you can follow me [here on Medium](https://medium.com/@CodingDoug) to get [the next part to this series](https://medium.com/p/kotlin-android-a-brass-tacks-experiment-wrap-up-2b37e3ac8957) (in addition to future blogs and series!). And for even faster updates, [follow me on Twitter](https://twitter.com/CodingDoug)!\n\n","author":"Doug Stevenson","date":"2016-03-08","type":"article","categories":["Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Exploring the Kotlin standard library","url":"http://beust.com/weblog/2015/10/30/exploring-the-kotlin-standard-library/","body":"\n[Standard.kt](https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/util/Standard.kt) is part of the Kotlin library and it defines some essential functions. What’s really striking about this source file is that it’s less than fifty lines long and that each of the function it defines (less than ten) is a one liner. Yet, each of these functions is very powerful. Here is a quick overview of the most important ones.\n\n## let()\n\n```kotlin\nfun T.let(f: (T) -> R): R = f(this)\n```\n\n`let()` is a scoping function: use it whenever you want to define a variable for a specific scope of your code but not beyond. It’s extremely useful to keep your code nicely self-contained so that you don’t have variables “leaking out”: being accessible past the point where they should be.\n\n```kotlin\nDbConnection.getConnection().let { connection ->\n}\n// connection is no longer visible here\n```\n\n`let()` can also be used as an alternative to testing against null:\n\n```kotlin\nval map : Map = ...\nval config = map[key]\n// config is a \"Config?\"\nconfig?.let {\n // This whole block will not be executed if \"config\" is null.\n // Additionally, \"it\" has now been cast to a \"Config\" (no question mark)\n}\n```\n\n## apply()\n\n```kotlin\nfun T.apply(f: T.() -> Unit): T { f(); return this }\n```\n\n`apply()` defines an extension function on all types. When you invoke it, it calls the closure passed in parameter and then returns the receiver object that closure ran on. Sounds complicated? It’s actually very simple and extremely useful. Here is an example:\n\n\n```kotlin\nFile(dir).apply { mkdirs() }\n```\n\nThis snippet turns a `String` into a `File` object, calls `mkdirs()` on it and then returns the file. The equivalent Java code is a bit verbose:\n\n```java\nFile makeDir(String path) {\n File result = new File(path);\n result.mkdirs();\n return result;\n}\n```\n\n`apply()` turns this kind of ubiquitous code into a one liner.\n\n## with()\n\n```kotlin\nfun with(receiver: T, f: T.() -> R): R = receiver.f()\n```\n\n`with()` is convenient when you find yourself having to call multiple different methods on the same object. Instead of repeating the variable containing this object on each line, you can instead “factor it out” with a with call:\n\n```kotlin\nval w = Window()\nwith(w) {\n setWidth(100)\n setHeight(200)\n setBackground(RED)\n}\n```\n\n## run()\n\n```kotlin\nfun T.run(f: T.() -> R): R = f()\n```\n\n`run()` is another interesting one liner from the standard library. Its definition is so simple that it looks almost useless but it’s actually a combination of `with()` and `let()`, which reinforces what I was saying earlier about the fact that because all these functions from the standard library are regular functions, they can be easily combined to create more powerful expressions.\n\n## Tying it all together\n\nOf course, it’s actually possible (and encouraged) to combine these functions:\n\n```kotlin\nfun configurationFor(id: String) = map[id]?.let { config ->\n config.apply {\n buildType = \"DEBUG\"\n version = \"1.2\"\n }\n}\n```\n\n This code looks up a Config object from an id and if one is found, sets a few additional properties on it and then returns it. But we can simplify this code even further. This time, I’m providing a fully self-contained snippet so you can copy and paste it directly into [Try Kotlin](http://try.kotlinlang.org/) in order to run it yourself:\n\n```kotlin\nclass Config(var buildType: String, var version: String)\n\nval map = hashMapOf()\n\nfun configurationFor(id: String) = map[id]?.let { config ->\n config.apply {\n buildType = \"DEBUG\"\n version = \"1.2\"\n }\n}\n```\n\nDon’t you feel that this combination of `let()` and `apply()` feels a bit boilerplatey? Let’s rewrite it a bit more idiomatically:\n\n```kotlin\nfun configurationFor(id: String) = map[id]?.apply {\n buildType = \"DEBUG\"\n version = \"1.2\"\n}\n```\n\n Let’s unpack this rather dense snippet:\n\n* Looking up a value on a hash map can be done either with `get()` or with the bracket notation, which is preferred.\n* Since the key might not be present in the map, we use the safe dereference operator `?.` which guarantees that we will only enter `apply()` if the result is non null.\n* Inside the `apply()` block, the this object is a `Config`, which lets us invoke functions on this object without any prefix. In this case, all we have is properties, but obviously, you could invoke regular functions just as well.\n* Once that code has run, the altered `Config` is returned.\n\n## use()\n\n```kotlin\nfun T.use(block: (T) -> R): R\n```\n\nAnother interesting function of the standard library is [use()](https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/io/ReadWrite.kt#L154), which gives us the equivalent of [Java’s try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) and of C#’s [using](https://msdn.microsoft.com/en-us/library/yh598w02.aspx?f=255&MSPPError=-2147217396) statement.\n\nThis function applies to all objects of type `Closeable` and it automatically closes its receiver on exit. Note that as opposed to Java and C#, Kotlin’s `use()` is a regular library function and **not** directly baked in the language with a special syntax. This is made possible by Kotlin’s extension functions and closure syntax used coinjointly.\n\n```java\n// Java 1.7 and above\nProperties prop = new Properties();\ntry (FileInputStream fis = new FileInputStream(\"config.properties\")) {\n prop.load(fis);\n}\n// fis automatically closed\n```\n\n```kotlin\n// Kotlin\nval prop = Properties()\nFileInputStream(\"config.properties\").use {\n prop.load(it)\n}\n// FileInputStream automatically closed\n```\n\nBecause Kotlin’s version is just a regular function, it’s actually much more composable than Java’s. For example, did you want to return this prop object after loading it?\n\n```kotlin\n// Kotlin\nfun readProperties() = Properties().apply {\n FileInputStream(\"config.properties\").use { fis ->\n load(fis)\n }\n}\n```\n\nThe `apply()` call tells us that the type of this expression is that of the object `apply()` is invoked on, which is `Properties`. Inside this block, `this` is now of type `Properties`, which allows us to call `load()` on it directly. In between, we create a `FileInputStream` that we use to populate this property object. And once we call `use()` on it, that `FileInputStream` will be automatically closed before this function returns, saving us from the ugly `try/catch/finally` combo that Java requires.\n\nYou will find a lot of these constructs in the [Kobalt build tool](http://beust.com/kobalt) code, feel free to browse it.\n\n","author":"Cédric Beust","date":"2015-10-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin & Android: A Brass Tacks Experiment, Part 1.","url":"https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-1-3e5028491bcc#.5c7ixfzdv","body":"\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*UN-S8ELMC2kpHf4tJKfbLQ.png)\n_Disclaimer: I am a Google employee, but the views expressed in this article are not those of my employer._\n\n### Kotlin & Android: A Brass Tacks Experiment, Part 1\n\nOne topic that’s been gaining popularity over the past year in the world of Android development is the [Kotlin](https://kotlinlang.org/)® language for the [JVM](https://en.wikipedia.org/wiki/Java_virtual_machine) from [JetBrains](https://www.jetbrains.com/). JetBrains is the same crew who created [IntelliJ Idea](https://www.jetbrains.com/idea/), which is the foundation for [Android Studio](http://developer.android.com/tools/studio/index.html). Kotlin takes aim at the age and perceived uncoolness of the Java® language with fresh and popular language features. I imagine that the crew at JetBrains imagines it could potentially become a replacement for Java® programming for all kinds of development on the JVM. Because it’s 100% inter-operable with the Java language, you can choose to use as much or as little Kotlin in your project as you like. And because it has a relatively small standard library, it’s suitable for development on mobile devices with limited resources.\n\nKotlin can do anything the Java language can do and more, but often with a more concise and pleasant syntax. There is full IDE support in IntelliJ and Android Studio. Because I’ve been deeply involved with Android since 2009, my specific interest in Kotlin is to discover what it _uniquely_ offers to Android developers. So I’m cutting through the hype in this blog series and getting down and dirty with Kotlin’s best language features, to see if I can make something truly useful.\n\nIn this first of a series of blog posts, I’ll go over the cleanest possible path to get Kotlin integrated into a new Android project. But if you’re looking to get straight to the code already, then go ahead and jump to [part 2](https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-2-c67661cfdf5f)!\n\n#### Configuring an Android Project with Kotlin\n\nThe [official docs](https://kotlinlang.org/docs/tutorials/kotlin-android.html) on getting started with Kotlin will show you how to install the Kotlin IDE plugin, and use that to modify an Android project’s Gradle config to add support for compiling Kotlin source. I don’t recommend this particular process, because I found the result of the automation to be less than satisfactory. While the changes it makes to the project’s Gradle build files might technically work, they don’t seem to be consistent with the way that new Android projects are typically set up.\n\nTo be frank, I have never been a fan of any Android Studio plugin that tries to guess changes to make to Android builds — more often than not, they botch things up, and I have to redo everything it did to clean it up to my liking. Gradle build files are actually source code, and automated processes are not really good at making changes to existing code! So, if you’re picky like me, take the extra minute to configure your project manually.\n\nIf you want to follow along, we’ll take four quick steps to get up and running:\n\n1. Create a new Android project.\n2. Modify the Gradle scripts to include the Kotlin Gradle plugin and standard library.\n3. Apply the Kotlin plugin for IntelliJ or Studio.\n4. Convert a Java class to Kotlin.\n\nFirst, create a new Android project using a template that adds an activity. When you have that, there are just five important lines of code to add across two build.gradle files, which I will highlight below. Let’s modify the top level build.gradle buildscript stanza with a couple of new lines:\n\n```kotlin\nbuildscript {\n ext.kotlin_version = '1.0.0'\n repositories {\n jcenter()\n }\n dependencies {\n classpath 'com.android.tools.build:gradle:1.5.0'\n classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n }\n}\n```\n\nThis adds the Kotlin Gradle plugin into the build. Note the definition of the Kotlin version string defined in ext.kotlin_version. We’ll use it twice: once here in the buildscript classpath, and once in the app compile dependencies, and it must be the same in both places. You should of course use the latest version published via Maven. You can find the latest version documented [here](https://kotlinlang.org/docs/reference/using-maven.html).\n\nNext, apply the kotlin-android plugin after the Android plugin in the app’s own build.gradle after the standard Android plugin. This makes the project Kotlin-aware and adds a Kotlin compile step to the build, so that all the classes generated by both the Java and Kotlin languages get bundled together in the final app:\n\n```kotlin\napply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\n```\n\nBy convention, Kotlin files want to live under src/main/kotlin, but they could also live alongside Java files in src/main/java. So, let’s be conventional and tell Gradle to recognize a new source directory for Kotlin source within the Android project definition:\n\n```kotlin\nandroid {\n sourceSets {\n main.java.srcDirs += 'src/main/kotlin'\n }\n}\n```\n\nDon’t forget to create that directory because we’ll use it later. You’ll also need a compile dependency on Kotlin’s standard library, using the version variable from the buildscript:\n\n```kotlin\ndependencies {\n compile \"org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version\"\n}\n```\n\nBut how big is this library we’re adding? This is a great question. Every Android developer should be asking this question every time a new compile dependency is added. However, we’ll save that discussion for a later post in the series.\n\nAt this point, you should be able to do a command line Gradle build as you would normally with gradlew, and you can also build and deploy an APK from Android Studio. Nothing should change except the size of the app, which grows with the Kotlin standard library.\n\nSo that’s the Kotlin Gradle plugin, and adding it to your project like this is sufficient to build and run Kotlin code in the project. But you’ll probably also want IDE support for Kotlin language features. If you haven’t already installed the Kotlin plugin for IntelliJ or Android Studio, now is a good time for that.\n\nInstalling the IDE plugin is just like any other. You can find that under Preferences → Plugins → Install JetBrains plugin. Be sure to restart the IDE after installation. With that, you’re done with setup. I’ve found that the IDE support for Kotlin is almost as good as for the Java language, but I would expect as much, since JetBrains makes both the IDE and Kotlin!\n\n#### From Java to Kotlin the Easy Way\n\nOne interesting feature of the IDE plugin is its action for converting Java source to Kotlin source. The plugin is smart enough to replace Java idioms with Kotlin idioms while retaining full runtime compatibility. If you’ve created a new Android project to try this out, go find the main activity that was generated for you, select it in the project explorer on the left, and invoke the IDE action called “Convert Java File to Kotlin File”. You can do that by bringing up the action selector with Command-Shift-A (on OSX), then typing that action name. The plugin also provides a finger-bending keyboard shortcut for this action (on OSX it’s Option-Shift-Command-K). So, enjoy typing that! Note that the [official documentation for this conversion](https://kotlinlang.org/docs/tutorials/kotlin-android.html) currently does not suggest 100% correct behavior for this action, but I haven’t encountered a problem so far.\n\nIf you convert a Java file like this, you’ll end up with a Kotlin .kt file in place of the original .java file like this:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*IPZCPTYVWIku8lAI0G9FGw.png)\n\n_MainActivity converted from Java to Kotlin_\n\nNotice that MainActivity has a Kotlin K logo on it now (but the file extension .kt is hidden here). Since we configured and created a dedicated source folder for Kotlin, as you can also see above, why don’t we move the newly converted Kotlin file to the space for Kotlin? It’s just like refactoring a Java file by moving it into a new folder or package by dragging it in the project explorer. Be sure to retain the existing package name of the class in the kotlin source directory so that the project still runs.\n\nIf you only want to use Kotlin in a project, you are free to delete the java source dir completely and put all Kotlin files in the kotlin space. With that, your project will look something like this:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*N5JYjlzzAcvzeSpTJ0TK6g.png)\n\n_MainActivity moved from java source dir to kotlin source dir_\n\nI’m sure you’ve already started to dig around in the converted activity, so you’ve probably already got a taste for what Kotlin looks like. I’ll point out a couple things that look different from the Java language. You’ll never see the keyword “new” in Kotlin; constructors are invoked simply by treating the name of the class as a function and passing it arguments. Also, the types of variables are typically missing from a declaration with val (final) or var (variable), and Kotlin can usually figure out what the type is.\n\nI’ll leave it up to you to make the initial leap from Java world to Kotlin world, and we’ll continue [next time](https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-2-c67661cfdf5f) with the beginning of a small project to see what Kotlin can uniquely offer Android developers. If you follow me, [@CodingDoug](https://medium.com/@CodingDoug), here on Medium, or [the same on Twitter](https://twitter.com/codingdoug), you’ll get notified as soon as new parts are available in this series!\n\n","author":"Doug Stevenson","date":"2016-02-01","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"SDCast #41: в гостях Андрей Бреслав, руководитель проекта Kotlin в компании JetBrains","url":"https://sdcast.ksdaemon.ru/2016/03/sdcast-41/","body":"\n![sd-podcast-logo](https://sdcast.ksdaemon.ru/wp-content/uploads/2014/06/sd-podcast-logo-200x200.png) Рад представить вам 41-й выпуск подкаста! Этот эпизод посвящен языку Kotlin, у меня в гостях Андрей Бреслав, руководитель проекта Kotlin в компании JetBrains.\n\nВ начале выпуска мы поговорили о том, зачем вообще нужен еще один язык, Андрей рассказал про историю и предпосылки появления Kotlin, как все начиналось и развивалось.\n\nОбсудили так же общие теоретические аспекты разработки языков программирования: чем разработка языка отличается от разработки каких-либо других программных продуктов, какие компоненты являются основой для построения языка, на какие аспекты следует обращать особое внимание и как правильно заложить архитектуру.\n\nТак же Андрей рассказал, почему в качестве платформы была выбрана JVM, рассказал некоторые технические подробности реализации проекта. Подробно рассказал про interop с Java, о том, как можно начать использовать Kotlin в уже существующем проекте на Java сейчас, и как они у себя, в компании JetBrains уже начали это делать.\n\nНе обошли мы сторой и социальную составляющую проекта. Код языка Kotlin выложен в open source на github. Андрей рассказал про сообщество, которое сформировалось вокруг проекта, и как они с ним взаимодействуют, обсуждают запросы на новый функционал, баг-репорты и все прочее.\n\nВ завершение выпуска, Андрей поделился планами по развитию языка как в ближайшем будущем, так и в долгосрочной перспективе.\n\nСсылки на ресурсы по темам выпуска:\n\n* Андрей в соц сетях:\n * [Twitter](https://twitter.com/abreslav)\n * [Facebook](https://fb.com/abreslav)\n * [ВКонтакте](https://vk.com/abreslav)\n * [LinkedIn](https://www.linkedin.com/in/abreslav)\n* [Основной сайт проекта kotlinlang.org](https://kotlinlang.org/)\n* [Репозиторий на github](https://github.com/JetBrains/kotlin)\n* [Пост в блоге проекта о релизе 1.0](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/)\n* Несколько видео докладов про Kotlin Андрея Бреслава и Дмитрия Жемерова:\n * [Что такое Kotlin? Введение](https://www.youtube.com/watch?v=HWyd1gYMkl0)\n * [Kotlin: самое сложное — совместимость](https://www.youtube.com/watch?v=LWFx4QWrTyo)\n * [Kotlin для Android: коротко и ясно](https://www.youtube.com/watch?v=VU_L2_XGQ9s)\n * [Kotlin: сессия вопросов и ответов со встречи JUG.ru 04.03.2016](https://www.youtube.com/watch?v=YOmdOTlhZa8)\n\n\n","author":"Андрей Бреслав, Константин Буркалев","date":"2016-03-11","type":"article","categories":["Kotlin","Podcast"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":{"url":"https://sdcast.ksdaemon.ru/podlove/file/159/s/download/SDCast-41.ogg","size":22683272}},{"title":"Kotlin 1.0.1 is Here!","url":"http://blog.jetbrains.com/kotlin/2016/03/kotlin-1-0-1-is-here/","body":"\nIt’s been a month since we released Kotlin 1.0, and while our user base roughly doubled during this time, we prepared the first bugfix update.\n\nKotlin 1.0.1 starts a series of 1.0.X versions delivering safe bug fixes and performance improvements to the language (as well as other parts of the project), and new features to our tools and integrations. This time it’s only relatively small IDE features, but bigger things are on the horizon for 1.0.2 and later.\n\n## Changes in 1.0.1\n\nPlease find the full change log [here](https://github.com/JetBrains/kotlin/blob/1.0.1/Changelog.md). Some numbers and highlights:\n\n\n* it’s 47 fixes in the compiler, library and Gradle plugin improvements (performance),\n* Compatibility with Gradle 2.12,\n* IDE features:\n * Compatibility with IDEA 2016,\n * Kotlin Education Plugin (for IDEA 2016),\n * [KT-9752](https://youtrack.jetbrains.com/issue/KT-9752) More usable file chooser for “Move declaration to another file”,\n * [KT-9697](https://youtrack.jetbrains.com/issue/KT-9697) Move method to companion object and back,\n* and 39 assorted fixes in the IDE.\n\nWe thank the participants of the EAP who tried the preview builds and reported feedback. Please join the [EAP](https://discuss.kotlinlang.org/t/kotlin-1-0-1-eap/1525) and let’s make Kotlin better together!\n\n","author":"Andrey Breslav","date":"2016-03-16","type":"article","categories":["Kotlin","Release"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Quasar and Kotlin - a Powerful Match","url":"http://blog.paralleluniverse.co/2015/06/04/quasar-kotlin/","body":"\nJune 04, 2015\n\nFollowing the release of [Kotlin M12](http://blog.jetbrains.com/kotlin/2015/05/kotlin-m12-is-out/) and of [Quasar 0.7.0](http://blog.paralleluniverse.co/2015/05/29/quasar-pulsar-0-7-0/) introducing support for it, let’s now have a closer look at how Kotlin and Quasar work together.\n\n[Kotlin](http://kotlinlang.org/) is JetBrains’ fun, statically-typed, safe, interoperable and expressive language targeting the JVM, Android and JavaScript. Pragmatic and efficient, it also features an excellent [IntelliJ Idea](https://www.jetbrains.com/idea/) integration from the start (which is my own and many other folks’ favourite IDE BTW). Finally our joint work with the Kotlin team has made Quasar on Kotlin smooth, natural and fast.\n\nEnabling Quasar support for Kotlin in your project is as easy as adding `quasar-kotlin` as a dependency and using one of Kotlin plugins for build systems, for example [Gradle’s](http://kotlinlang.org/docs/reference/using-gradle.html). We’ll start from a bird’s-eye view of our [ping-pong actor test](https://github.com/puniverse/quasar/blob/master/quasar-kotlin/src/test/kotlin/co/paralleluniverse/kotlin/actors/PingPong.kt) and then we’ll zoom in:\n\n```kotlin\ndata class Msg(val txt: String, val from: ActorRef)\n\nclass Ping(val n: Int) : Actor() {\n Suspendable override fun doRun() {\n val pong = ActorRegistry.getActor(\"pong\")\n for(i in 1..n) {\n pong.send(Msg(\"ping\", self())) // Fiber-blocking\n receive { // Fiber-blocking\n when (it) {\n \"pong\" -> println(\"Ping received pong\")\n else -> null // Discard\n }\n }\n }\n pong.send(\"finished\") // Fiber-blocking\n println(\"Ping exiting\")\n }\n}\n\nclass Pong() : Actor() {\n Suspendable override fun doRun() {\n while (true) {\n // snippet Kotlin Actors example\n receive(1000, TimeUnit.MILLISECONDS) { // Fiber-blocking\n when (it) {\n is Msg -> {\n if (it.txt == \"ping\")\n it.from.send(\"pong\") // Fiber-blocking\n }\n \"finished\" -> {\n println(\"Pong received 'finished', exiting\")\n return // Non-local return, exit actor\n }\n is Timeout -> {\n println(\"Pong timeout in 'receive', exiting\")\n return // Non-local return, exit actor\n }\n else -> defer()\n }\n }\n // end of snippet\n }\n }\n}\n\npublic class Tests {\n Test public fun testActors() {\n spawn(register(\"pong\", Pong()))\n spawn(Ping(3))\n }\n}\n```\n\n## Data\n\n```kotlin\ndata class Msg(val txt: String = \"Hello\", val from: ActorRef)\n```\n\nYes, Kotlin supports [data classes](http://kotlinlang.org/docs/reference/data-classes.html). This means that when you need a one-liner to hold some info, it can be a one-liner for real. Kotlin will generate sensible `equals`, `hashCode`, `toString` as well as deconstruction support, so that you can easily write:\n\n```kotlin\nval myMsg = Msg(txt = \"Hi\", from = me)\n// ...\nval (txt, from) = myMsg\n```\n\nAdd to that type inference, a shorter construction syntax for class instances (no `new` needed), default parameter values, invocation with named arguments and support for immutability with `val` declarations and you’ve got a full toolbox for your message-crafting actor needs (and more). Should you need to copy your message in full or in part:\n\n```kotlin\nval myNewMsg = myMsg.copy(txt = \"Howdy\")\n```\n\n`Pair` and `Triple` are included in the standard library, too [1](#fn:bigger-tuples).\n\n`ActorRef` represents a reference to a Quasar actor whose `send` can accept values of any type, including `null`s. `Any` is the utmost super-type in Kotlin and the question mark specifies that it is _nullable_ here (the default in Kotlin is non-nullable). If a value is of a non-nullable type, Kotlin will check against nulls at compile time for Kotlin code, and at runtime for values produced by Java invocations [2](#fn:java-interop).\n\n## Classes\n\n```kotlin\nclass Ping(val n: Int) : Actor()\n```\n\n`Ping` inherits from the base `Actor` Kotlin class [3](#fn:untyped-actors) and it is _final_. This is the default in Kotlin because designing for inheritance is difficult and control over class hierarchies is important, so inheritance support must be declared explicitly through the `open` class modifier.\n\nIn Kotlin you can define your primary constructor without specifying a body and declare its parameters as properties by prefixing `val` (immutable) or `var` (mutable), which you need to do if you plan to use them not only during initialization but in methods too. A parent class’ constructor invocation is inline with inheritance declaration, and a short `:` is enough to specify that.\n\nWe declare `n` as a property because our actor is going to use it in its `doRun` execution body:\n\n```kotlin\nSuspendable override fun doRun() {\n // ...\n}\n```\n\nThe `override` modifier is mandatory and the `Suspendable` annotation allows our actor’s fiber to invoke fiber-blocking calls such as `send` and `receive`. [Kotlin annotations](http://kotlinlang.org/docs/reference/annotations.html) don’t need to be preceded by `@` in most situations, which allow them to appear naturally as user-defined modifiers. Kotlin also supports [JSR-269 annotation processing](http://blog.jetbrains.com/kotlin/2015/05/kapt-annotation-processing-for-kotlin/).\n\n## Fiber-blocking Kotlin actors\n\n```kotlin\nval pong = ActorRegistry.getActor(\"pong\")\nfor(i in 1..n) {\n pong.send(Msg(\"ping\", self())) // Fiber-blocking\n receive { // Fiber-blocking\n when (it) {\n \"pong\" -> println(\"Ping received pong\")\n else -> null // Discard\n }\n }\n}\npong.send(\"finished\") // Fiber-blocking\n```\n\n`Ping` leads the game here: it gets a reference to `Pong` from the global registry, then `send`s and `receive`s ping pongs `n` times, after which it tells `Pong` to bail out before quitting itself. It’s once again as simple as it was with regular threads: just straightforward imperative constructs and blocking calls, only much more efficient thanks to fibers.\n\nKotlin makes it even sweeter though. Apart from the nice looping construct with [ranges](http://kotlinlang.org/docs/reference/ranges.html), let’s have a deeper look at the [_selective receive_](http://docs.paralleluniverse.co/quasar/#sending-and-receiving-messages-actorref) block:\n\n```kotlin\nreceive { // Fiber-blocking\n when (it) {\n \"pong\" -> println(\"Ping received pong\")\n else -> null // Discard\n }\n}\n```\n\nIt feels like a new construct, doesn’t it? This neat small DSL employs no less than 3 advanced Kotlin features: [lambdas](http://kotlinlang.org/docs/reference/lambdas.html) with [inline functions](http://kotlinlang.org/docs/reference/inline-functions.html) and the type-safe [matching `when` expression](http://kotlinlang.org/docs/reference/control-flow.html#when-expression).\n\nThe block following `receive` is actually a single-argument _lambda_ for which Kotlin provides an extremely compact syntax. You can even avoid naming the argument: it’ll be called `it` as in this case, and of course you can skip brackets along the way. This is `receive`’s Kotlin signature:\n\n```kotlin\ninline protected fun receive(proc: (Any) -> Any?)\n```\n\n`proc` is a selection and transformation function: it can accept (and possibly transform), discard or delay an incoming message. If a message is accepted, it is returned by the `receive` call.\n\nHere `proc` contains only a matching `when` expression, which is type-checked for matching exhaustiveness and, of course, type correctness [4](#fn:when). Yielding `null` in `proc` discards the value and _doesn’t_ return from `receive`; calling `defer()` will skip the message in the current `receive` call, leaving it in the mailbox, while producing any other value (even `Unit` like the `println` statement in the `\"pong\"` branch) will make the `receive` call return and control flow will proceed to the next iteration in the `for` loop.\n\nLet’s take a glance at `Pong`’s main loop:\n\n```kotlin\nreceive(1000, TimeUnit.MILLISECONDS) { // Fiber-blocking\n when (it) {\n is Msg -> {\n if (it.txt == \"ping\")\n it.from.send(\"pong\") // Fiber-blocking\n }\n \"finished\" -> {\n println(\"Pong received 'finished', exiting\")\n return // Non-local return, exit actor\n }\n is Timeout -> {\n println(\"Pong timeout in 'receive', exiting\")\n return // Non-local return, exit actor\n }\n else -> defer()\n }\n}\n```\n\nIn this case we’re calling a selective receive with a timeout [5](#fn:receive). Two more notable Kotlin features and two API features work together here to make this code short, readable and powerful. As for Kotlin:\n\n* `is Msg` is a type check that performs a _smart cast_, so that `it` acquires the `Msg` type in its clause and properties can be accessed as simply as `it.txt` and `it.from`.\n* `return` in the _inline lambda_ performs a _non-local return_, that is it makes the `doRun` invocation return, after which the actor will quit [6](#fn:only-inline).\n\nThe Kotlin Actors API adds the following:\n\n* `defer()` implements _selective receive_ by skipping messages in the current `receive` call.\n* A `Timeout` message can be used to handle timeouts directly in the processing lambda if you so wish, without even returning from the `receive` call.\n\n## Now with plain, healthy fibers\n\nThere’s now a neat Kotlin port of the `quasar-gradle-template` in the `kotlin` branch. I built it very quickly by copying and pasting the previous Java source to a new Kotlin file in IntelliJ Idea and confirming Kotlin conversion! Of course then I polished it to my tastes and added the semantics that were missing in Java, and here’s the result:\n\n```kotlin\npackage testgrp\n\n// ...\n\nfun doAll(): Int? {\n val increasingToEcho = Channels.newIntChannel(0) // Synchronizing channel (buffer = 0)\n val echoToIncreasing = Channels.newIntChannel(0) // Synchronizing channel (buffer = 0)\n\n val increasing = Fiber(SuspendableCallable(@Suspendable {\n var curr = 0\n for (i in 0..9) {\n Fiber.sleep(1000)\n println(\"INCREASER sending: \" + curr)\n increasingToEcho.send(curr)\n curr = echoToIncreasing.receive()\n println(\"INCREASER received: \" + curr)\n curr++\n println(\"INCREASER now: \" + curr)\n }\n println(\"INCREASER closing channel and exiting\")\n increasingToEcho.close()\n curr;\n })).start()\n\n val echo = Fiber(SuspendableCallable(@Suspendable {\n val curr: Int?\n while (true) {\n Fiber.sleep(1000)\n curr = increasingToEcho.receive()\n println(\"ECHO received: \" + curr)\n\n if (curr != null) {\n println(\"ECHO sending: \" + curr)\n echoToIncreasing.send(curr)\n } else {\n println(\"ECHO detected closed channel, closing and exiting\")\n echoToIncreasing.close()\n break\n }\n }\n })).start()\n\n increasing.join()\n echo.join()\n\n return increasing.get()\n}\n\npublic fun main(args: Array) {\n doAll()\n}\n```\n\nWait, where are the classes? Functions can be toplevel in Kotlin: a class is generated for each package with static methods corresponding to toplevel functions. We’re not doing real OOP here, so we won’t define classes and Kotlin allows us to skip them altogether if we don’t need them. That makes sense and eliminates boilerplate, doesn’t it?\n\nAs for the packages, they are completely _disjoint_ from source files organization in directories and that allows freedom and convenience. Of course with great powers comes great responsibility but why should I bother creating directories only in order to use packages, when my project is made of a single source file (or a handful of them)? And since Kotlin is very concise, this situation will arise more often than you think.\n\nNow, where are the types instead? This example is strongly typed but most of the types are inferred. There are only a handful of them:\n\n```kotlin\nfun doAll(): Int?\n```\n\nIn Kotlin, `public` and `protected` functions need to be _explicitly typed_ both in the argument and return type because they _are public API_ and we don’t want to alter it by mistake because we changed the body (and type inference has adjusted types consequently without us noticing) [7](#fn:public-api).\n\nIn this case though, this function has _module-level_ access (“internal”). Why does it still need to be fully typed? Because it has a block body which can have complex control flow and type inference could easily confuse the reader (and hinder maintainability).\n\n```kotlin\nval increasing = Fiber(SuspendableCallable(@Suspendable {\n```\n\nWhat’s happening here? We’re passing a `Suspendable`-annotated lambda instead of a full blown object expression (which is more pleasant than Java’s anonymous classes anyway), similarly to what we’d do with Java 8 lambdas. The `SuspendableCallable` constructor helps Kotlin’s type inference engine to interoperate with Java functional interfaces (this will be simplified very soon so that there’ll be no need to explicitly mention `SuspendableCallable`). Finally we don’t need to declare actual type parameters for `Fiber` (no ugly _diamonds_ either, sorry for people that like them) and of course not even for the `increasing` local.\n\n```kotlin\nvar curr: Int?\n```\n\nSince we know that the value of the `curr` mutable local value will come from Java, we know it could become `null` (and at some point it actually needs to, in order to represent a closed Quasar channel). We’re telling Kotlin that in advance, so that it won’t emit fail-fast runtime checks that will trigger an exception when `curr` gets assigned a `null` value.\n\nBy contrast no type declaration is needed by the `curr` mutable local in the `increasing` fiber, because it will be inferred to be `Int` and since it will be managed completely within Kotlin code, the compiler will check statically that it will never become `null`:\n\n```kotlin\nvar curr = 0 // Int\n```\n\n## What else is there?\n\nKotlin has loads of other advanced and convenient features that make it a pleasure to use not just with Quasar but in every occasion:\n\n* Type-checking covers [null safety](http://kotlinlang.org/docs/reference/null-safety.html) and allows [smart type casts](http://kotlinlang.org/docs/reference/typecasts.html); imperative programmers will enjoy [returns and jumps](http://kotlinlang.org/docs/reference/returns.html) and [ranges](http://kotlinlang.org/docs/reference/ranges.html) as well as [excellent Java interoperability](http://kotlinlang.org/docs/reference/java-interop.html) and [unchecked exceptions](http://kotlinlang.org/docs/reference/exceptions.html#checked-exceptions).\n* Functional guys will appreciate [higher-order functions and local functions](http://kotlinlang.org/docs/reference/functions.html) as well as [first-class method](http://kotlinlang.org/docs/reference/reflection.html#function-references) and [property accessor](http://kotlinlang.org/docs/reference/reflection.html#property-references) references.\n* DSL craftpeople will make good use of functional features, convenient syntax shortcuts and [type-safe builders](http://kotlinlang.org/docs/reference/type-safe-builders.html).\n* OOP has no shortage of tools either: [extension functions](http://kotlinlang.org/docs/reference/extensions.html), [trait-like interfaces](http://kotlinlang.org/docs/reference/interfaces.html), [compact and common sense inheritance with sensible defaults](http://kotlinlang.org/docs/reference/classes.html), [singleton objects](http://kotlinlang.org/docs/reference/object-declarations.html#object-expressions), [object expressions](http://kotlinlang.org/docs/reference/object-declarations.html#object-expressions), [generics with declaration-site variance and type projections](http://kotlinlang.org/docs/reference/generics.html), [feature-rich enums](http://kotlinlang.org/docs/reference/enum-classes.html), [delegation](http://kotlinlang.org/docs/reference/delegation.html), [properties accessors](http://kotlinlang.org/docs/reference/properties.html#getters-and-setters) and [delegated properties](http://kotlinlang.org/docs/reference/delegated-properties.html).\n\n* * *\n\n1. If you need bigger tuples it’s probably an hint that you’d better give them a more specific name for readability’s sake. [↩](#fnref:bigger-tuples)\n2. See [Java interoperability, platform types](http://kotlinlang.org/docs/reference/java-interop.html) and [null safety](http://kotlinlang.org/docs/reference/null-safety.html). [↩](#fnref:java-interop)\n3. Kotlin actors are always untyped because typed actors are useful only in very simple cases, like short-lived transient actors, but not so much in more complex situations. [↩](#fnref:untyped-actors)\n4. `when` supports type maching, value matching against arbitrary expressions and range matching; see [control flow](http://kotlinlang.org/docs/reference/control-flow.html). [↩](#fnref:when)\n5. The timeout overload is `inline protected fun receive(timeout: Long, unit: TimeUnit?, proc: (Any) -> Any?)` and it is non-blocking if the timeout is 0. [↩](#fnref:receive)\n6. This is possible only with inline lambdas. [↩](#fnref:only-inline)\n7. This is likely to become only a warning in the future. [↩](#fnref:public-api)\n\n\n","author":"Fabio","date":"2015-06-04","type":"article","categories":["Kotlin","Quasar","Fibers"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin ternary operator","url":"https://gist.github.com/naixx/9d94c1498c4d45ffda3a","body":"\n## Motivation\n\nKotlin is very expressive language, but like Scala it lacks of ternary operator. Currently language provided alternative `if` looks a bit verbose. \n\n```kotlin\nval result = if (myExpression) 1 else 2\n```\nCompared to a classical Java or C++ variant\n\n```java\nint result = myExpression ? 1 : 2\n```\n\nUnlike Scala, Kotlin allows only fixed names for operators, so we cant fully reproduce classic syntax, but we can have something similar\n\n```kotlin\nval result = myExpression % 1 / 2\n\n```\n\nIf you want to use complex boolean expression, you can wrap it in braces\n\n```kotlin\nval result = (a == null && b > 5) % 1 / 2\n```\n\nThe impact I see here is temporary object creation, probably `inline` can't help.\n\n```kotlin\nclass Ternary(val expr: Boolean, val then: T) {\n public fun div(elze: T): T = if (expr) then else elze\n}\n\npublic fun Boolean.mod(a: T): Ternary = Ternary(this, a)\n```\n\n","author":"naixx","date":"2016-11-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Concurrency Primitives in Kotlin","url":"https://blog.egorand.me/concurrency-primitives-in-kotlin/","body":"\nI've recently started reading [\"Android Concurrency\" by G. Blake Meike](https://www.goodreads.com/book/show/26260944-android-concurrency), and so far I can highly recommend this great book: it contains quite a lot of insight into how various Android concurrency mechanisms work, when to prefer one approach over the other and how to get the best of the tools at your disposal. I decided to follow along with the code examples and recreate them on my computer, and since I'm deeply in love with Kotlin, I thought it would be a great idea to translate the examples into Kotlin on the go. In one of the first chapters the author revisits concurrency basics in Java, and when I started rewriting the code examples in Kotlin, I was quite surprised to find out that:\n\n* There's no `synchronized` keyword in Kotlin\n* There's no `volatile` keyword in Kotlin\n* Kotlin's `Any`, which is analogous to Java's `Object`, doesn't have `wait()`, `notify()` and `notifyAll()` methods\n\nSo how does concurrency work in Kotlin? This question has been asked on the [Kotlin forum](https://discuss.kotlinlang.org/t/concurrency-in-kotlin/858) and here's the answer from Andrey Breslav, Kotlin Project Lead:\n\n> Kotlin deliberately has no constructs for concurrency built into the language. We believe this should be handled by libraries.\n\nAlthough Kotlin doesn't have these things built into the language, it still provides quite a bunch of low-level concurrency tools. Let's take a look at what's in store.\n\n### Creating Threads\n\nThere are two ways to create a thread in Java: extending the `Thread` class, or instantiating it and passing a `Runnable` through the constructor. Since you can easily use Java classes in Kotlin, both solutions work just fine. Here's how you'd subclass `Thread`:\n\n```kotlin\nobject : Thread() { \n override fun run() {\n println(\"running from Thread: ${Thread.currentThread()}\")\n }\n}.start()\n```\n\nThis code uses Kotlin's [`Object Expressions`](https://kotlinlang.org/docs/reference/object-declarations.html#object-expressions) to create an anonymous class and override the `run()` method. And here's how to pass a `Runnable` to a newly created instance of `Thread`:\n\n```kotlin\nThread({ \n println(\"running from lambda: ${Thread.currentThread()}\")\n}).start()\n```\n\nYou don't see a `Runnable` here: in Kotlin it can easily be replaced with a [lambda expression](https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions). Is there a better way? Sure! Here's how you can instantiate and start a thread Kotlin-style:\n\n```kotlin\nthread(start = true) { \n println(\"running from thread(): ${Thread.currentThread()}\")\n}\n```\n\nNeat, isn't it? We're using the `thread()` function, which magically hides away all the boilerplate code. In fact, there's zero magic inside `thread()`:\n\n```kotlin\npublic fun thread(start: Boolean = true, isDaemon: Boolean = false, contextClassLoader: ClassLoader? = null, name: String? = null, priority: Int = -1, block: () -> Unit): Thread { \n val thread = object : Thread() {\n public override fun run() {\n block()\n }\n }\n if (isDaemon)\n thread.isDaemon = true\n if (priority > 0)\n thread.priority = priority\n if (name != null)\n thread.name = name\n if (contextClassLoader != null)\n thread.contextClassLoader = contextClassLoader\n if (start)\n thread.start()\n return thread\n}\n```\n\nIt's just a very convenient wrapper function that's a joy to use.\n\n### Synchronized Methods and Blocks\n\n`synchronized` is not a keyword in Kotlin, it's replaced with an [`@Synchronized`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-synchronized/) annotation. The declaration of a synchronized method in Kotlin will look like this:\n\n```kotlin\n@Synchronized fun synchronizedMethod() {\n println(\"inside a synchronized method: ${Thread.currentThread()}\")\n}\n```\n\nThe annotation has the same effect as Java's `synchronized`: it'll mark the JVM method as synchronized. For synchronized blocks you'll have to use the [`synchronized()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/synchronized.html) function, which takes a `lock` as the parameter:\n\n```kotlin\nfun methodWithSynchronizedBlock() { \n println(\"outside of a synchronized block: ${Thread.currentThread()}\")\n synchronized(this) {\n println(\"inside a synchronized block: ${Thread.currentThread()}\")\n }\n}\n```\n\nThe code looks and behaves pretty similar to the Java variant.\n\n### Volatile Fields\n\nSame story, there's no `volatile` keyword in Kotlin, but there's the [`@Volatile`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-volatile/index.html) annotation:\n\n```kotlin\n@Volatile private var running = false\n\nfun start() { \n running = true\n thread(start = true) {\n while (running) {\n println(\"Still running: ${Thread.currentThread()}\")\n }\n }\n}\n\nfun stop() { \n running = false\n println(\"Stopped: ${Thread.currentThread()}\")\n}\n```\n\nThe behavior is similar to `@Synchronized`: `@Volatile` will mark the JVM backing field as volatile.\n\n### wait(), notify() and notifyAll()\n\nEvery class in Kotlin inherits from `Any`, but `Any` doesn't declare `wait()`, `notify()` and `notifyAll()`, meaning that these methods can't be called on a Kotlin class. But you still can use an instance of `java.lang.Object` as a lock and call the methods on it. Here's a solution to the Producer/Consumer problem that uses `Object` as the lock:\n\n```kotlin\nprivate val lock = java.lang.Object()\n\nfun produce() = synchronized(lock) { \n while (items >= maxItems) {\n lock.wait()\n }\n Thread.sleep(rand.nextInt(100).toLong())\n items++\n println(\"Produced, count is $items: ${Thread.currentThread()}\")\n lock.notifyAll()\n}\n\nfun consume() = synchronized(lock) { \n while (items <= 0) {\n lock.wait()\n }\n Thread.sleep(rand.nextInt(100).toLong())\n items--\n println(\"Consumed, count is $items: ${Thread.currentThread()}\")\n lock.notifyAll()\n}\n```\n\nDoes it look hacky? Well, it is. Truth is that if you're relying on such low-level constructs in your code - most likely you're doing something wrong. Nowadays there's a ton of high-level concurrency mechanisms for every purpose in both Java and Kotlin. [Here's](http://stackoverflow.com/questions/35520583/why-there-are-no-constructs-for-concurrency-in-kotlin) a great Stackoverflow answer that provides a list of tools available for writing concurrent code in Kotlin.\n\nAll code samples from this article are available on [GitHub](https://github.com/Egorand/kotlin-concurrency-primitives).\n\n### Conclusion\n\nAlthough they're not used frequently, it's still important to know and understand the basic concurrency tools. Turns out those work a bit differently in Kotlin than in Java, but all major mechanisms are supported. And remember that Kotlin interacts really well with Java, so you can just rely on Java classes if the Kotlin counterparts are missing. Have fun!\n\nIf you've enjoyed this short article, please share it with your network using one of the buttons below. Thanks, and have a Merry Christmas!\n\n","author":"Egor Andreevici","date":"2016-12-23","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Solving the Josephus problem in Kotlin","url":"https://blog.frankel.ch/solving-the-josephus-problem-in-kotlin","body":"\nI recently stumbled upon a [post](http://www.danvk.org/josephus.html) telling about the [Josephus problem](https://en.wikipedia.org/wiki/Josephus_problem) and trying to solve it in different scripting languages. For the sake of brevity, here’s the problem (taken from the referenced post):\n\n> Flavius Josephus was a roman historian of Jewish origin. During the Jewish-Roman wars of the first century AD, he was in a cave with fellow soldiers, 40 men in all, surrounded by enemy Roman troops. They decided to commit suicide by standing in a ring and counting off each third man. Each man so designated was to commit suicide...Josephus, not wanting to die, managed to place himself in the position of the last survivor.\n\n> In the general version of the problem, there are n soldiers numbered from 1 to n and each k-th soldier will be eliminated. The count starts from the first soldier. What is the number of the last survivor?\n\nIt seemed like a good challenge to test my building Kotlin skills. Here’s the solution I’ve come up with. First, the test class, using TestNG and a data provider – it’s the perfect use-case:\n\n```kotlin\nclass JosephusTest {\n\n @DataProvider\n fun data(): Array> {\n return arrayOf(\n arrayOf(2, 1, 0),\n arrayOf(3, 1, 0),\n arrayOf(10, 1, 0),\n arrayOf(3, 2, 0),\n arrayOf(4, 2, 1)\n )\n }\n\n @Test(dataProvider = \"data\")\n fun circle_of_size_and_step_should_survive_position(size: Int, step: Int, expectedPosition: Int) {\n val circle = Circle(size, step)\n val survivor = circle.findSurvivor()\n assertEquals(survivor.position, expectedPosition)\n }\n}\n```\n\nNow, the code:\n\n```kotlin\nclass Soldier(val position: Int) {\n var state = State.Living\n lateinit var next: Soldier\n fun suicide() {\n state = State.Dead\n }\n fun isDead() = state == State.Dead\n}\n\nenum class State {\n Living, Dead\n}\n\nclass Circle(private val size: Int, private val step: Int) {\n\n private val first = Soldier(0)\n\n init {\n var person = first\n while (person.position < size - 1) {\n person = createNext(person)\n }\n val last = person\n last.next = first\n }\n\n private fun createNext(soldier: Soldier): Soldier {\n val new = Soldier(soldier.position + 1)\n soldier.next = new\n return new\n }\n\n fun findSurvivor(): Soldier {\n var soldier: Soldier = first\n var numberOfDead = 0\n while (numberOfDead < size - 1) {\n var count: Int = 0\n while (count < step) {\n soldier = nextLivingSoldier(soldier)\n count++\n }\n soldier.suicide()\n numberOfDead++\n }\n return nextLivingSoldier(soldier)\n }\n\n private fun nextLivingSoldier(soldier: Soldier): Soldier {\n var currentSoldier = soldier.next\n while (currentSoldier.isDead()) {\n currentSoldier = currentSoldier.next\n }\n return currentSoldier\n }\n}\n```\n\nThis code works fine and the tests are successful.\n\nHowever, while trying to code the solution, I realized that there were no data-structure implementing circular linked lists neither in Java nor in Kotlin. I had thus to implement my own circular data-structure, but without implementing common collection features.\n\nNow, my problem with the above code is that while the `Soldier` class looks fine by me, the `Circle` class doesn’t. There are too many vars in `Circle` and it feels too much like imperative programming. The lack of `for(;;)` in Kotlin forces me to use a `while` with an outside variable – twice: `count` and `numberOfDead`.\n\nI’ve been thinking that I could improve the situation by changing the data-structure. I just don’t know how... Now, Kotlin and FP gurus, do you have any proposal?\n\n","author":"Nicolas Franke","date":"2016-03-06","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Digest 2016.Q1","url":"http://blog.jetbrains.com/kotlin/2016/04/kotlin-digest-2016-q1/","body":"\n\nWelcome the Kotlin Digest of Q1 2016. It was in this quarter that Kotlin 1.0 was released, and naturally the number of articles and coverage received has substantially increased.\nWe want to thank everyone for their contributions, and highlight some of the most notable articles and blog posts.\n\n
    ![2016Q1Cover](http://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/04/2016Q1Cover.png?resize=640%2C320)
    \n\nBy the way, you can [join us on slack](http://kotlinslackin.herokuapp.com/) and subscribe to the _#feed_ channel, where we push quite a bit of interesting content as it appears.\n\n# General Articles\n\n* [Kotlin 1.0 Is Now Available and the Newest JVM Language Is a Breeze](https://dzone.com/articles/kotlin-10-is-now-available)\n* Two Q&A of Kotlin’s project lead Andrey Breslav on [DZone](https://dzone.com/articles/a-qa-with-andrey-breslav-on-kotlin) and [InfoQ](http://www.infoq.com/news/2016/02/kotlin-10-released)\n* [Kotlin: a new JVM language you should try](https://opencredo.com/kotlin/) by [Rafal Gancarz](https://twitter.com/rafalgancarz)\n* [Kotlin: The Ying and Yang of Programming Languages](https://www.linkedin.com/pulse/kotlin-ying-yang-programming-languages-eric-kolotyluk) by [Eric Kolotyluk](https://www.linkedin.com/in/eric-kolotyluk-7462253?trk=pulse-det-athr_prof-art_hdr)\n* [Kotlin – 2 Years On](https://yobriefca.se/blog/2016/02/24/kotlin-2-years-on/) by [James Hughes](https://twitter.com/kouphax)\n\n# Android\n\n* [Kotlin awesome tricks for Android](http://antonioleiva.com/kotlin-awesome-tricks-for-android/) by Antonio Leiva (author of [Kotlin for Android Developers](https://leanpub.com/kotlin-for-android-developers) book)\n* Series of posts [Kotlin & Android: A Brass Tacks Experiment](https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-1-3e5028491bcc#.d0dy6mji7) by [Doug Stevenson](https://www.linkedin.com/in/doug-stevenson-95509b22) (Developer Advocate in Google)\n* [Getting Started with Kotlin and Anko on Android](https://realm.io/news/getting-started-with-kotlin-and-anko/) by [Donn Felker](https://twitter.com/donnfelker) from Realm\n* [Roberto Perez](https://www.linkedin.com/in/raperez) shared his expirience in [creating an AndroidWear watchface using Kotlin](https://medium.com/@robj.perez/creating-an-androidwear-watchface-using-kotlin-e5f725813fa9)\n\n# Web Development\n\n* Two great posts by [Sébastien Deleuze](https://twitter.com/sdeleuze) from Spring: [Developing Spring Boot applications with Kotlin](https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin) and [A Geospatial Messenger with Kotlin, Spring Boot and PostgreSQL](https://spring.io/blog/2016/03/20/a-geospatial-messenger-with-kotlin-spring-boot-and-postgresql)\n* Three-part article by [Mike Gehard](https://twitter.com/mikegehard) from Pivotal: [The Journey of a Spring Boot application from Java 8 to Kotlin: The Application Class](http://engineering.pivotal.io/post/spring-boot-application-with-kotlin/)\n* [Nicolas Frankel](https://twitter.com/nicolas_frankel) wrote about his [experiments with Spring Boot, Vaadin, and Kotlin](https://dzone.com/articles//playing-with-spring-boot-vaadin-and-kotlin)\n* [Writing a RESTful backend using Kotlin and Spring Boot](https://medium.com/@dime.kotevski/writing-a-restful-backend-using-kotlin-and-spring-boot-9f162c96e428) by [Dimitar Kotevski](https://twitter.com/dimitar_)\n* [Rest API plumbing with kotlin](https://medium.com/@gz_k/rest-api-plumbing-with-kotlin-b161af052178) by [Gaëtan Zoritchak](https://twitter.com/gz_k)\n\n# Ecosystem\n\n* [TornadoFX](https://dzone.com/articles/a-new-javafx-app-framework-for-kotlin-tornadofx) — a new JavaFX app framework for Kotlin\n* [KillerTask](http://inaka.net/blog/2016/01/25/killertask-the-solution-to-asynctask-implementation/) — a solution to AsyncTask implementation\n* [PaperParcel](http://blog.bradcampbell.nz/introducing-paperparcel/) — a new annotation processor that automatically generates type-safe [Parcelable](http://developer.android.com/intl/es/reference/android/os/Parcelable.html) boilerplate code for Kotlin and Java\n* [Kotlin + RxJava = Functional Powerhouse](http://tomstechnicalblog.blogspot.ru/2016/02/kotlin-rxjava-what-rxjava-should-be.html)\n* [Kotlin : Retrofit + RxAndroid + Realm](https://medium.com/@ahmedrizwan/kotlin-retrofit-rxandroid-realm-39d7be5dc9dc)\n* [Using Dagger 1 and Kotlin](http://michaelevans.org/blog/2016/02/17/using-dagger-1-and-kotlin/)\n* [Using libGDX with Kotlin](http://obviam.net/index.php/libgdx-and-kotlin/) and [creating a simple 2D platformer](http://obviam.net/index.php/libgx-and-kotlin-2d-platformer-prototyping/)\n\n# Features overwiew\n\n* [Kotlin for Java Developers: 10 Features You Will Love About Kotlin](http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/)\n* [10 Features I Wish Java Would Steal From the Kotlin Language](http://blog.jooq.org/2016/03/31/10-features-i-wish-java-would-steal-from-the-kotlin-language/)\n* [Kotlin — Love at first line](https://medium.com/@dime.kotevski/kotlin-love-at-first-line-7127befe240f#.kan4x5dyg)\n* [An Introduction to Kotlin](https://objectpartners.com/2016/02/23/an-introduction-to-kotlin/)\n* [Kotlin, superseding the language we love](http://www.endran.nl/blog/kotlin-super-seeding-the-language-we-love-2)\n* [Kotlin, the somewhat obscure modern Android-friendly programming language](https://medium.com/math-camp-engineering/kotlin-3e963864db9e#.4hxqlfnvn)\n\n# Technical\n\n* [A Very Peculiar, but Possibly Cunning Kotlin Language Feature](http://blog.jooq.org/2016/02/22/a-very-peculiar-but-possibly-cunning-kotlin-language-feature/)\n* [Solving the Josephus problem in Kotlin](https://blog.frankel.ch/solving-the-josephus-problem-in-kotlin) & [update](https://blog.frankel.ch/feedback-jospehus-problem)\n* [Kotlin: Easily storing a list in SharedPreferences with Custom Accessors](http://blog.dennislysenko.com/2016/01/22/kotlin-easily-storing-a-list-in-sharedpreferences-with-custom-accessors/)\n* [Using Kotlin Extensions for Rx-ifying](http://vishnurajeevan.com/2016/02/13/Using-Kotlin-Extensions-for-Rx-ifying/)\n* [Using Mockito for unit testing with Kotlin (1/x)](http://makingiants.com/blog/using-mockito-for-unit-tests-with-kotlin-1x/)\n* [Using Kotlin For Tests in Android](https://medium.com/@sergii/using-kotlin-for-tests-in-android-6d4a0c818776)\n\n# Kotlin series\n\n* [Juan Saravia](https://twitter.com/juanchosaravia) started his series of stories about learning Kotlin, while developing an Android App\n * [Introduction: A few words about this](https://medium.com/@juanchosaravia/learn-kotlin-while-developing-an-android-app-introduction-567e21ff9664)\n * [Part 1: Configuring Android Studio with Kotlin](https://medium.com/@juanchosaravia/learn-kotlin-while-developing-an-android-app-part-1-e0f51fc1a8b3)\n * [Part 2: MainActivity.kt: Syntax, Null Safety and more...](https://medium.com/@juanchosaravia/learn-kotlin-while-developing-an-android-app-part-2-e53317ffcbe9)\n * [Part 3: NewsFragment.kt: Extension Functions, Android Extensions...](https://medium.com/@juanchosaravia/keddit-part-3-extension-functions-android-extensions-and-more-faa7d232f232)\n * [Part 4: RecyclerView — Delegate Adapters & Data Classes with Kotlin](https://medium.com/@juanchosaravia/keddit-part-4-recyclerview-delegate-adapters-data-classes-with-kotlin-9248f44327f7)\n * [Part 5: Kotlin, RxJava & RxAndroid](https://medium.com/@juanchosaravia/keddit-part-5-kotlin-rxjava-rxandroid-105f95bfcd22)\n * [Part 6: API — Retrofit & Kotlin](https://medium.com/@juanchosaravia/keddit-part-6-api-retrofit-kotlin-d309074af0)\n* Kotlin Month series by Jacob Zimmerman\n * [Post 1: Assorted Features](https://programmingideaswithjake.wordpress.com/2016/02/27/kotlin-month-post-1-assorted-features/)\n * [Post 2: Inheritance and Defaults](https://programmingideaswithjake.wordpress.com/2016/03/05/kotlin-month-post-2-inheritance-and-defaults/)\n * [Post 3: Safety](https://programmingideaswithjake.wordpress.com/2016/03/13/kotlin-month-post-3-safety/)\n * [Post 4: Properties](https://programmingideaswithjake.wordpress.com/2016/03/19/kotlin-month-post-4-properties/)\n* by [Ciro Rizzo](https://github.com/cirorizzo):\n * [My Kotlin Adventure](http://www.cirorizzo.net/2016/01/23/kotlin-at-glance/)\n * [Kotlin Coding](http://www.cirorizzo.net/2016/02/03/kotlin-code/)\n * Building a Kotlin project ([part 1](http://www.cirorizzo.net/2016/03/04/building-a-kotlin-project/) and [part 2](http://www.cirorizzo.net/2016/03/04/building-a-kotlin-project-2/))\n\n\n","author":"Roman Belov","date":"2016-04-06","type":"article","categories":["Kotlin","Digest"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Taking Kotlin for a ride","url":"https://www.linkedin.com/pulse/taking-kotlin-ride-hadi-tok?published=t","body":"\nI have read about Kotlin and tried it on their online editor ([http://try.kotlinlang.org/](http://try.kotlinlang.org/)) previously. But I was wondering about the work required to make Kotlin work on an existing project. So I took kotlin for a ride over the weekend on a new branch and converted one of the fragments to Kotlin and make it work with the rest of the project, in language aspect and project structure aspect. So I will not talk about the features of Kotlin but mostly how to make it work on an existing Android project.\n\nThe first thing needed is to install Kotlin plugin on Android Studio. It could be installed as a JetBrains plugin in plugins section on Android Studio Preferences. It has three main features:\n\n* Editor support\n* Kotlin setup on project\n* Converting Java code to Kotlin\n\nThe editor support is pretty good. I don’t really felt anything lacking when writing code with Kotlin compared to Java. It is pretty important while learning a new language. You would need all the help from the IDE.\n\nYou can configure Kotlin in your project by Tools>Kotlin>Configure Kotlin in Project. The only problem I had was the apply plugin: 'kotlin-android' line on the app build.gradle file which is placed above `apply plugin: 'com.android.application'` so I had to moved under. Other than it was fine.\n\nAs I mentioned I converted one of the fragments that uses different features of Java and android to Kotlin. On the syntax side I only had a problem with `Iterator.remove()` apparently which doesn’t have an equivalent on Kotlin. Instead I used `Iterable.filter`. I think it has more straight forward usage than iterator for loop. This was the only compilation problem I had.\n\nOne thing I had worries about was the annotation processing. It is used on Butterknife and dagger. I was using apt plugin ([https://bitbucket.org/hvisser/android-apt](http://bitbucket.org/hvisser/android-apt)) for this purpose. But it didn’t work with kotlin. I haven’t received and compilation or build exceptions but I received an exception on runtime regarding to `lateinit` (`UninitializedPropertyAccessException`) on a variable supposed to be binded with Butterknife. Kotlin examples page on github([https://github.com/JetBrains/kotlin-examples](http://github.com/JetBrains/kotlin-examples)) came to help at this point. I modified my annotations and changed the apt plugin to Kotlin apt plugin ([http://blog.jetbrains.com/kotlin/2015/05/kapt-annotation-processing-for-kotlin/](http://blog.jetbrains.com/kotlin/2015/05/kapt-annotation-processing-for-kotlin/)) after then everything worked as expected.\n\nOther thing that is useful to know is the json deserialization. With a simple module addition to the Jackson library this is also pretty straight forward. You can find the instructions on the github page(https://github.com/FasterXML/jackson-module-kotlin)\n\nAs conclusion I haven’t decided to move to Kotlin yet. I am impressed the easy integration and interoperability with Java. I am planning to use on one or two fragments that will be developed from scratch and try to have more experience on it. But So far my experience has been good.\n\n","author":"Hadi Tok","date":"2016-10-16","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"App State as a tree","url":"https://medium.com/lewisrhine/app-state-as-a-tree-a8eb6b26dd1b#.f9j7p0x89","body":"\nWe tend to think of app state as just the current values at a given time. But what if we thought about state at a higher level? Wouldn’t it be useful to have more information, not just of the values of our properties, but the state of an application as a whole.\n\nImage your whole app broken into trees. Let’s say for example, a restaurant review app, why a restaurant review app? I don’t know! I’m just trying to think of anything that’s not a To Do app, okay. Let’s draw out what the state tree of this kind of app would be.\n\nI am using a site named [Sketchboard.io](https://sketchboard.io/). I highly recommend them.\n\nFirst, what are the components of the app we are going to need?\n\nList of nearby restaurants: A list of all restaurants near the user.\n\nList of reviewed restaurants: All the restaurants the user has already reviewed, if any.\n\nCompose a review: Where the user will go to write or edit a review.\n\nHere it is sketched out:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*k5oltMaFoEOkhR80Cm2Q9Q.png)\n\nNow that we have our core components we can start to build out the trees for each one.\n\nFor this example we are only going to worry about the ‘Restaurants Nearby’ component. We know that to get the data we are going to need to get the user’s GPS location. Then, we need to send a request to some kind of rest API, like Yelp or Foursquare, using that location. So it’s pretty clear the first state this tree would have would be a **Loading State**.\n\nOnce we receive our response from the API we can move down the tree to a **Done State** and come to our first branch. At this point there are going to be three possible outcomes.\n\n**Ready State** we have our list of restaurants. \n**Empty State** there were no nearby restaurants found. \n**Error State** we get some kind of error, either from the GPS or from the server.\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*uua9-C2PEPeT_9XJqxWwYQ.png)\n\nThere are a few things to notice here. We moved the ‘List of Restaurants’ down to our **Ready State**. So now, the only way for the app to get access to that list is once we’ve made it down to that branch. Also notice that in our **Done State** we have a function called **reloadData**. Now every state down the tree has the ability move back up to the loading state.\n\nLooking at this, it’s easy to see how helpful this approach can be. When we are getting data from the tree in our UI layer we know exactly what state the app is in. We know that if the tree is in a **Loading State** all we can do is tell the user and wait. Once we are updated with the new state of the tree we know “Ok, is the list ready for us? Cool get the list and display it.” If it’s empty or there was an error, we don’t even have access to the list.\n\nIt also gives an easy to glance at map of your app. Need to add a feature? You can start by looking at where in your app branches need to be changed or created, and how it will affect the rest of the app.\n\n“Ok. So yeah, drawing stuff is all well and good. But how can we do it in code?” Turns out Kotlin has a feature perfect for this.\n\nSealed classes are best described as enums on steroids. For this context you can think of them as a group of type safe abstract classes. This is what the above tree would look like as a sealed class\n\n```kotlin\nsealed class RestaurantNearby() {\n sealed class Loading() : RestaurantNearby() {\n //Code for getting Location, and API call\n sealed class Done() : Loading() {\n fun reloadData() {}\n class Ready(val restaurants: List) : Done()\n class Empty() : Done()\n class Error(val message: String, val throwable: Throwable?) : Done()\n }\n }\n}\n```\n\nThis coupled with a Kotlins ‘when’ interacting with this sealed class is super simple.\n\n```kotlin\nwhen (restaurantNearby) {\n is RestaurantNearby.Loading -> // Tell user the data is loading\n \n is RestaurantNearby.Loading.Done -> {\n restaurantNearby.reloadData() // Attach this function to some user feedback.\n \n when (restaurantNearby) {\n is RestaurantNearby.Loading.Done.Ready -> restaurantNearby.restaurants // Do something with this list.\n \n is RestaurantNearby.Loading.Done.Empty -> // Tell the user there was no data found.\n \n is RestaurantNearby.Loading.Done.Error -> {\n restaurantNearby.message // Show this message to the user.\n restaurantNearby.throwable // Catch this and act on it as needed.\n }\n }\n }\n}\n```\n \nNow there is a big part of this idea that is missing. How do you pass these classes around? How should you set it? Should it be immutable? The idea of building your state’s into trees is part of a library I am working on called [Akorn](https://github.com/LewisRhine/Akorn). It is a Flux style architecture, open source library, that uses RxJava to reactivity pass your state trees. Akron is still a little baby and I would love for people check it out.\n\n","author":"Lewis Rhine","date":"2016-11-21","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Релиз Kotlin 1.0, языка программирования для JVM и Android.","url":"http://www.opennet.ru/opennews/art.shtml?num=43882","body":"\nКомпания Jetbrains, развивающая интегрированную среду разработки IntelliJ IDEA, [представила](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/) первый значительный релиз объектно-ориентированного языка программирования [Kotlin 1.0](https://kotlinlang.org/), позволяющего создавать приложения, скомпилированные для последующего выполнения внутри стандартной виртуальной машины Java (JVM) или Android. Дополнительно поддерживается преобразование программ в JavaScript-представление для запуска внутри браузера, но данная функциональность пока отнесена к экспериментальным возможностям.\n\nВыпуск 1.0 позиционируется как первый выпуск, готовый для промышленного применения. Все дальнейшие обновления будут выпускаться с учётом сохранения обратной совместимости. Исходные тексты [открыты](http://github.com/jetbrains/kotlin) под лицензией Apache 2.0. Плагины с поддержкой Kotlin подготовлены для интегрированных сред разработки IntelliJ IDEA, Eclipse и Android Studio. Из систем сборки поддерживаются Maven, Gradle и Ant.\n\nЯзык развивается в санкт-петербургском центре разработки компании JetBrains c целью создания максимально совместимого с Java языка программирования, одновременно лишённого ограничений и недостатков Java, от которых Java не может избавиться из-за необходимости обеспечения обратной совместимости. При этом проекты на Kotlin полностью совместимы с компонентами на языке Java - из программ Kotlin можно вызывать Java-классы и наоборот, из Java вызывать компоненты, написанные на Kotlin. Кроме возможности использования штатных Java-бибилиотек для Kotlin подготовлена большая библиотека классов, оптимизированная для генерации байткода минимального размера.\n\nИз отличительных черт языка Kotlin можно выделить ориентацию на обеспечение более высокой безопасности за счет реализации статических проверок для выявления таких проблем как разыменование NULL-указателей. Среди других особенностей, имеющих отношение к безопасности, отмечается отсутствие raw-типов, полное сохранение информации о типах в процессе выполнения и реализация массивов в виде [инварианта](http://confluence.jetbrains.net/display/Kotlin/Basic+types#Basictypes-Arrays). Из расширенных языковых возможностей отмечается поддержка [функций высшего порядка](http://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F_%D0%B2%D1%8B%D1%81%D1%88%D0%B5%D0%B3%D0%BE_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0), [вывода типов](http://ru.wikipedia.org/wiki/%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2) значений на основании выражения, использование уточняющих \"[примесей](http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%81%D1%8C_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29)\" (mixin) и [делегирования](http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BB%D0%B5%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29).\n\n","author":"Open Source","date":"2016-02-16","type":"article","categories":["Kotlin","JVM"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"Kanvas: generating a simple IDE from your ANTLR grammar","url":"https://tomassetti.me/kanvas-generating-simple-ide-antlr-grammar/","body":"\n![](https://i0.wp.com/tomassetti.me/wp-content/uploads/2017/01/Kanvas-1.png?resize=1024%2C768)\n\n## What is an editor?\n\nAn editor is, for me, the main tool I use for work. As a Language Engineer I create new languages, I use existing ones and I need different tools to work with them. I would like to be able to hack all of them together, in a customized IDE I can grow for me. This is why I am working on Kanvas, the hackable editor. Which is [on GitHub](https://github.com/ftomassetti/kanvas), of course.\n\nIn many cases I need a simple text editor for my DSLs and I tend to build them using ANTLR. I will need other stuff, like tabular or graphical projections, simulators and more but I need to start somewhere, right? Also, I think right now there is not an easy way to get a standalone editor for a DSL, with **minimal dependencies and a simple structure**. There is not a light option on the menu. Time to add one.\n\n## Getting an editor from your grammar quickly\n\nOnce you define the grammar of your language there is a lot of information you can extract from it. I think you should be able to get as much value as possible from it for free, with the possibility to customize it further, if needed. This is similar to the idea behind Xtext (minus the 400 pages you need to read to understand EMF).\n\nHow quickly can you get an editor for your ANTLR grammar? You create a new project for your editor, add Kanvas as a dependency and register which languages do you intend to support:\n\n```kotlin\nfun main(args: Array) {\n languageSupportRegistry.register(\"sm\", smLangSupport)\n val kanvas = Kanvas()\n SwingUtilities.invokeLater {\n kanvas.createAndShowKanvasGUI()\n kanvas.addTab(\"My SM\", languageSupport = smLangSupport)\n }\n}\n```\n\nand add these lines to support your language:\n\n```kotlin\nobject smLangSupport : BaseLanguageSupport() {\n override val antlrLexerFactory: AntlrLexerFactory\n get() = object : AntlrLexerFactory {\n override fun create(code: String): Lexer = SMLexer(org.antlr.v4.runtime.ANTLRInputStream(code))\n }\n override val parserData: ParserData?\n get() = ParserData(SMParser.ruleNames, SMParser.VOCABULARY, SMParser._ATN)\n}\n```\n\nThis quickly. Less then 10 lines of code. We just need to specify the Lexer and Parser classes (_SMLexer_ and _SMParser_ in this example).\n\nIf you are wondering what language is that, that is Kotlin: a concise static language for the JVM, easily interoperable with Java.\n\n## Let’s improve it a little bit: syntax highlighting\n\nSo I have a simple language, I get an editor basically for free and I start using it. As first thing I want to define the style for the different kind of tokens. We are doing something simple, just setting the colors:\n\n```kotlin\nobject smLangSyntaxScheme : SyntaxScheme(true) {\n override fun getStyle(index: Int): Style {\n val style = Style()\n val color = when (index) {\n // Types\n SMLexer.STRING, SMLexer.INT, SMLexer.DECIMAL -> Color(42, 53, 114)\n\n // Literals\n SMLexer.STRINGLIT -> Color(21, 175, 36)\n SMLexer.INTLIT, SMLexer.DECLIT -> Color.BLUE\n\n // Comments\n SMLexer.COMMENT -> Color(170, 181, 171)\n\n // Operators\n SMLexer.ASTERISK, SMLexer.DIVISION, SMLexer.PLUS, SMLexer.MINUS -> Color.WHITE\n\n // Keywords\n SMLexer.VAR -> Color.GREEN\n SMLexer.INPUT -> Color(200, 250, 200)\n SMLexer.SM -> Color(200, 250, 200)\n SMLexer.EVENT -> Color(200, 250, 200)\n SMLexer.AS -> Color(50, 12, 96)\n\n // Identifiers\n SMLexer.ID -> Color.MAGENTA\n\n // Separators\n SMLexer.ARROW -> Color(50, 12, 96)\n SMLexer.COLON -> Color(50, 12, 96)\n SMLexer.ASSIGN -> Color(50, 12, 96)\n SMLexer.LPAREN, SMLexer.RPAREN -> Color.WHITE\n\n // Rest\n SMLexer.UNMATCHED -> Color.RED\n else -> null\n }\n if (color != null) {\n style.foreground = color\n }\n return style\n }\n}\n```\n\nWe are not setting certain tokens to be bold or in italic because we want to keep things simple. By the way, if you are interested in how syntax highlighting works in Kanvas, I described it in [this post](https://tomassetti.me/how-to-create-an-editor-with-syntax-highlighting-dsl/).\n\n## And then comes autocompletion\n\nNow, we get some limited autocompletion for free. We basically get autocompletion depending on the structure of the language, so our algorithm can tell us which keywords can be inserted in the current position or that in a certain position an identifier can be accepted. What the algorithm cannot not determine for free is which identifiers should suggest. Let’s implement a very simple logic: when we can insert an identifier we look at the preceeding tokens and use them to determine which suggestion to make. For example, when defining an input we could suggest “anInput” while when defining a variable we could suggest “aVar”:\n\n```kotlin\n override val propositionProvider: PropositionProvider\n get() = object : PropositionProvider {\n override fun fromTokenType(completionProvider: CompletionProvider,\n preecedingTokens: List, tokenType: Int): List {\n val res = LinkedList()\n var proposition : String? = this@smLangSupport.parserData!!.vocabulary.getLiteralName(tokenType)\n if (proposition != null) {\n if (proposition.startsWith(\"'\") && proposition.endsWith(\"'\")) {\n proposition = proposition.substring(1, proposition.length - 1)\n }\n res.add(BasicCompletion(completionProvider, proposition))\n } else {\n when (tokenType) {\n SMParser.ID -> {\n val determiningToken = preecedingTokens.findLast { setOf(SMLexer.SM, SMLexer.VAR, SMLexer.EVENT, SMLexer.INPUT).contains(it.type) }\n val text = when (determiningToken?.type) {\n SMLexer.SM -> \"aStateMachine\"\n SMLexer.EVENT -> \"anEvent\"\n SMLexer.INPUT -> \"aInput\"\n SMLexer.VAR -> \"aVar\"\n else -> \"someID\"\n }\n res.add(BasicCompletion(completionProvider, text))\n }\n }\n }\n return res\n }\n }\n```\n\nHere is the code. Is this enough? I do not know, but what I know is that this is a system small enough to be understandable and simple enough to be easily extended and customized. So I plan to use it for this small language, and improve the autocompletion as needed, specifically for this language. Organically and iteratively grow tool support is the name of the game.\n\n## Design goals: something similar to Sublime Text but open-source\n\nWe all love Sublime Text. I would like to have something inspired to it, but open-source. Why open-source? So that I can customize it as much as I want.\n\nThis is how it looks like for now:\n\n![](https://i1.wp.com/tomassetti.me/wp-content/uploads/2017/01/Kanvas_550.png?resize=500%2C500)\n\nYes, it is not yet as beautiful as Sublime Text. But this means I have space for improvement.\n\n## To Language Workbench or to not Language Workbench?\n\nI work routinely with Language Workbenches such as Jetbrains MPS and Xtext. They are great because they permit to obtain very good tool support very quickly. In many situations they are your best option. However, as every engineering choice, there are different aspects to consider. Jetbrains MPS and Xtext are very large and complex pieces of software, the kind of stuff that weight hundreds of MBs. To learn the internals of these platforms require a lot of work and a large effort. You can have a huge benefit by simply using those platforms. However they are not the best solution in all situations because in some situations you need to integrate your language with existing systems and thus you have to bend those Language Workbenches in ways they are not designed to. Maybe you want to embed your editor or tools in your existing platform, maybe you want to have a simple editor to use on a tablet, maybe you want tools to use from the command line. Maybe you want to hack a system together to fit your particular needs in some peculiar way. In those cases using a Language Workbench is not the right choice. You need something simple, something hackable. This is the approach I am experimenting it. To do that I am working on a few open-source projects and [writing a book](https://leanpub.com/create_languages).\n\n## Conclusions\n\nWill this fly? I do not know. I am having fun spending the few time I find on this project. And I feel it can be a good approach to get simple standalone editors for DSLs built with ANTLR. I would also like to use it as my sort of Kotlin-powered vim, a vim for the new millenium. With super-projectional-powers. Let’s see how this grows.\n\nAnd yes, I know that Atom describes itself as the hackable editor. But it is not hackable enough from my point of view.\n\n","author":"Federico Tomassetti","date":"2017-01-03","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin DSL: Anko","url":"https://docs.google.com/presentation/d/12mkyGQZO22kf0_6kp2K6xyFdpg0nBLqGtNcVR-cV4M8/pub","body":"\n\n[Kotlin DSL: Anko](https://docs.google.com/presentation/d/12mkyGQZO22kf0_6kp2K6xyFdpg0nBLqGtNcVR-cV4M8/pub)\n\n","author":"@maciekjanusz","date":"2016-04-06","type":"slides","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The Kobalt diaries: testing","url":"http://beust.com/weblog/2016/02/20/the-kobalt-diaries-testing/","body":"\nKobalt automatically detects how to run your tests based on the test dependencies that you declared:\n\n```kotlin\ndependenciesTest {\n compile(\"org.testng:testng:6.9.9\")\n}\n```\n\nBy default, Kobalt supports TestNG, JUnit and Spek. You can also configure how your tests run with the test{} directive:\n\n```Kotlin\ntest {\n args(\"-excludegroups\", \"broken\", \"src/test/resources/testng.xml\")\n}\n```\n\nThe full list of configuration parameters can be found in the [TestConfig](https://github.com/cbeust/kobalt/blob/master/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/TestDirective.kt#L6) class.\n\nAdditionally, you can define multiple test configurations, each with a different name. Each configuration will create an additional task named \"test\" followed by the name of that configuration. For example:\n\n```Kotlin\ntest {\n args(\"-excludegroups\", \"broken\", \"src/test/resources/testng.xml\")\n}\n\ntest {\n name = \"All\"\n args(\"src/test/resources/testng.xml\")\n}\n```\n\nThe first configuration has no name, so it will be launched with the task \"test\", while the second one can be run with the task \"testAll\".\n\nThe full series of articles on Kobalt can be found [here](http://beust.com/weblog/category/kobalt/).\n\n","author":"Cédric Beust","date":"2016-02-20","type":"article","categories":["Kotlin","Kobalt"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin for Data Science","url":"http://tomstechnicalblog.blogspot.com.by/2016/10/kotlin-for-data-science.html","body":"\n## Can Kotlin be an Effective Alternative for Python and Scala?\n\nAs I started diving formally into data science, I cannot help but notice there is a large gap between data science and software engineering. It is good to come up with prototypes, ideas, and models out of data analysis. However, executing those ideas is another animal. You can outsource the execution to a software engineering team, and that can go well or badly depending on a number of factors. In my experience, it is often helpful to do the execution yourself or at least offer assistance by modeling towards production.\n\nAlthough Python can be used to build production software, I find its lack of static typing causes difficulty in scaling. It does not easily plug in with large corporate infrastructures built on the Java platform either. Scala, although an undeniably powerful JVM language, is rather esoteric and inaccessible for those who do not have a software engineering background. But [Kotlin](http://kotlinlang.org/), a new JVM language by [JetBrains](https://www.jetbrains.com/) (the creator of [Intellij IDEA](https://www.jetbrains.com/idea/), [PyCharm](https://www.jetbrains.com/pycharm/), and dozens of other developer tools), has an active community, rapid growth and adoption, and might serve as a more accessible alternative to Scala.\n\n[Apache Spark](http://spark.apache.org/) is definitely a step in the right direction to close the gap between data science and software engineering, or more specifically, turning an idea into immediate execution. You can use [SparkR](https://spark.apache.org/docs/latest/sparkr.html) and [PySpark](http://spark.apache.org/docs/0.9.0/python-programming-guide.html) to interface R and Python with Spark. But if you want to use a production-grade JVM language, the only mainstream options seem to be Scala and Java. But Kotlin works out-of-the-box with Spark as well, since it is 100% interoperable with Java libraries.\n\n## A Comparison Between Python and Kotlin\n\nLet's take a look at a somehwat simple data analysis case study. We will leave Scala out and only compare Kotlin with Python. What I want to highlight is how Kotlin has the tactical conciseness of Python, and maybe even brings a little more to the table as a language for data analysis. Granted, there are not a lot of mainstream JVM data science libraries other than Apache Spark. But they do exist and perhaps there is room for growth. After all, Python caught up with R in a short time, and I am certainly not saying to drop your entire data analysis stack for Kotlin either. But the language may be worth keeping your eye on (and even exploring!).\n\nThis comparison was inspired by the social media example from the first chapter of [Data Science from Scratch](http://shop.oreilly.com/product/0636920033400.do) (Grus, _O'Reilly_). Let's start with declaring two sets of data, `users` and `friendships`. Using simply dicts, lists, and tuples without any classes, this is how it could be done in Python.\n\n**Python**\n\n```python\nusers = [ \n { \"id\" : 0, \"name\" : \"Hero\" }, \n { \"id\" : 1, \"name\" : \"Dunn\" }, \n { \"id\" : 2, \"name\" : \"Sue\" }, \n { \"id\" : 3, \"name\" : \"Chi\" }, \n { \"id\" : 4, \"name\" : \"Thor\" }, \n { \"id\" : 5, \"name\" : \"Clive\" }, \n { \"id\" : 6, \"name\" : \"Hicks\" }, \n { \"id\" : 7, \"name\" : \"Devin\" }, \n { \"id\" : 8, \"name\" : \"Kate\" }, \n { \"id\" : 9, \"name\" : \"Klein\" }, \n]\n \nfriendships = [ \n (0,1), \n (0,2), \n (1,2), \n (1,3), \n (2,3), \n (3,4), \n (4,5), \n (5,6), \n (5,7), \n (6,8), \n (7,8), \n (8,9)\n]\n```\n\nThe `users` is a `List` of `dict` items, and the `friendships` are a `List` of `Tuple` items. A feature of dynamic typing is you can be fast-and-loose creating data structures that maintain a raw data-like nature. There is no enforcement to uses classes or explicit types.\n\nThe equivalent to doing this in Kotlin would look like this:\n\n**Kotlin**\n\n```kotlin\nval users = listOf(\n mapOf(\"id\" to 0, \"name\" to \"Hero\"),\n mapOf(\"id\" to 1, \"name\" to \"Dunn\"),\n mapOf(\"id\" to 2, \"name\" to \"Sue\"),\n mapOf(\"id\" to 3, \"name\" to \"Chi\"),\n mapOf(\"id\" to 4, \"name\" to \"Thor\"),\n mapOf(\"id\" to 5, \"name\" to \"Clive\"),\n mapOf(\"id\" to 6, \"name\" to \"Hicks\"),\n mapOf(\"id\" to 7, \"name\" to \"Devin\"),\n mapOf(\"id\" to 8, \"name\" to \"Kate\"),\n mapOf(\"id\" to 9, \"name\" to \"Klein\")\n )\n \n val friendships = listOf(\n listOf(0,1), listOf(0,2), listOf(1,2), listOf(1,3), listOf(2,3), listOf(3,4),\n listOf(4,5), listOf(5,6), listOf(5,7), listOf(6,8), listOf(7,8), listOf(8,9)\n )\n```\n\nFor the `friendships`, we can actually create `Pair` items. Kotlin does not really encourage Tuples (or any collection with differing types) and we will see what it offers instead later with the [`data class`](https://kotlinlang.org/docs/reference/data-classes.html). But let's use [Pairs](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/) in this example instead using the `to` operator.\n\n```kotlin\nval friendships = listOf(\n 0 to 1, 0 to 2, 1 to 2, 1 to 3, 2 to 3, 3 to 4,\n 4 to 5, 5 to 6, 5 to 7, 6 to 8, 7 to 8, 8 to 9\n)\n```\n\nThis may look effective at first glance, and Kotlin is statically typed. It is inferring the type for `users` and `friendships` as `List>` and `List` respectively. Notice how `friendships` is a `List` containing `Map` items, meaning each item has a `String` for a key and an `Any` for the value. The reason for the `Any` is some values are `String` and others are `Int` (due to the \"id\" and \"name\"), and because the type is not consistent it cast them back down to `Any`. If we want to use Hero's \"id\", we need to cast it back up to an `Int` for it to be treated like an `Int` rather than a raw `Any`.\n\n```kotlin\nval herosId = users[0][\"id\"] as Int\n```\n\nOf course, if an \"id\" value is slipped in as a `String` accidentally this would throw an error. You can check if it is an `Int`, but at this point we are just fighting the statically-typed nature of Kotlin (just like Java and Scala). In Kotlin, we are much better off creating a `class` and doing things the statically-typed way. While this may make dynamic-typing advocates moan, check this out. Kotlin has a concise, readable way of declaring a class quickly and easily, even exceeding Python's standards\n\n**Python**\n\n```python\nclass User(Any):\n def __init__(self, id, name):\n self.id = id\n self.name = name\n \n def __str__(self):\n return \"{0}-{1}\".format(self.id, self.name)\n \nusers = [ \n User(0,\"Hero\"), \n User(1,\"Dunn\"), \n User(2,\"Sue\"), \n User(3,\"Chi\"), \n User(4,\"Thor\"), \n User(5,\"Clive\"), \n User(6,\"Hicks\"), \n User(7,\"Devin\"), \n User(8,\"Kate\"), \n User(9,\"Klein\"), \n]\n```\n\n**Kotlin**\n\n```kotlin\ndata class User(val id: Int, val name: String)\n \nval users = listOf(\n User(0, \"Hero\"),\n User(1, \"Dunn\"),\n User(2, \"Sue\"),\n User(3, \"Chi\"),\n User(4, \"Thor\"),\n User(5, \"Clive\"),\n User(6, \"Hicks\"),\n User(7, \"Devin\"),\n User(8, \"Kate\"),\n User(9, \"Klein\")\n )\n```\n\nNot too shabby, right? Technically, we did _less_ typing (as in keyboard typing) than Python (76 characters less to be exact, excluding spaces). And we achieved static typing in the process!\n\nKotlin is certainly a progressive language compared to Java, and it even has practical features like [data classes](https://kotlinlang.org/docs/reference/data-classes.html). We made our `User` a `data class`, which will automatically implement functionality typically used for classes holding plain data. It will implement `toString()` and `hashcode()`/`equals()` using the properties, as well as a nifty \"copy-and-modify\" builder by using a `copy()` function.\n\n**Kotlin**\n\n```kotlin\ndata class User(val id: Int, val name: String)\n \nval user = User(10,\"Tom\")\nval changedUser = user.copy(name = \"Thomas\")\n \nprintln(\"Old user: $user\")\nprintln(\"New user: $changedUser\")\n```\n\n**OUTPUT:**\n\n```\nOld user: User(id=11, name=Tom)\nNew user: User(id=11, name=Thomas)\n```\n\n> NOTE: In Kotlin, `val` precedes the declaration of an immutable variable. `var` precedes a mutable one.\n\nData classes are a valuable tool especially for working with data. And yes, Kotlin supports named arguments for constructors and functions as shown in the `copy()` function above.\n\nLet's return back to our example. Say we wanted to find the mutal friends between two Users. Traditionally in Python, you would create a series of helper functions to assist in this task.\n\n**Python**\n\n```python\nclass User(object):\n def __init__(self, id, name):\n self.id = id\n self.name = name\n \n def __str__(self):\n return \"{0}-{1}\".format(self.id, self.name)\n \nusers = [ \n User(0,\"Hero\"), \n User(1,\"Dunn\"), \n User(2,\"Sue\"), \n User(3,\"Chi\"), \n User(4,\"Thor\"), \n User(5,\"Clive\"), \n User(6,\"Hicks\"), \n User(7,\"Devin\"), \n User(8,\"Kate\"), \n User(9,\"Klein\"), \n]\n \nfriendships = [ \n (0,1), \n (0,2), \n (1,2), \n (1,3), \n (2,3), \n (3,4), \n (4,5), \n (5,6), \n (5,7), \n (6,8), \n (7,8), \n (8,9)\n]\n \ndef user_for_id(user_id):\n for user in users:\n if user.id == user_id:\n return user\n \n \n \ndef friends_of(user):\n for friendship in friendships:\n if friendship[0] == user.id or friendship[1] == user.id:\n for other_user_id in friendship:\n if other_user_id != user.id:\n yield user_for_id(other_user_id)\n \ndef mutual_friends_of(user, otherUser):\n for friend in friends_of(user):\n for other_friend in friends_of(otherUser):\n if (friend.id == other_friend.id):\n yield friend\n \n \n# print mutual friends between Hero and Chi \n \nfor friend in mutual_friends_of(users[0],users[3]):\n print(friend)\n```\n\n**OUTPUT:**\n\n```\n1-Dunn\n2-Sue\n```\n\nBut we can do something similar in Kotlin.\n\n**Kotlin**\n\n```kotlin\nfun main(args: Array) {\n \n data class User(val id: Int, val name: String)\n \n val users = listOf(\n User(0,\"Hero\"),\n User(1, \"Dunn\"),\n User(2, \"Sue\"),\n User(3, \"Chi\"),\n User(4, \"Thor\"),\n User(5, \"Clive\"),\n User(6, \"Hicks\"),\n User(7, \"Devin\"),\n User(8, \"Kate\"),\n User(9, \"Klein\")\n )\n \n \n val friendships = listOf(\n 0 to 1, 0 to 2, 1 to 2, 1 to 3, 2 to 3, 3 to 4,\n 4 to 5, 5 to 6, 5 to 7, 6 to 8, 7 to 8, 8 to 9\n )\n \n fun userForId(id: Int): User {\n for (user in users)\n if (user.id == id)\n return user\n throw Exception(\"User not found!\")\n }\n \n fun friendsOf(user: User): List {\n val list = mutableListOf()\n for (friendship in friendships) {\n if (friendship.first == user.id)\n list += userForId(friendship.second)\n if (friendship.second == user.id)\n list += userForId(friendship.first)\n }\n return list\n }\n \n fun mutualFriendsOf(user: User, otherUser: User): List {\n val list = mutableListOf()\n for (friend in friendsOf(user))\n for (otherFriend in friendsOf(otherUser))\n if (friend.id == otherFriend.id)\n list += friend\n \n return list\n }\n \n for (friend in mutualFriendsOf(users[0],users[3]))\n println(friend)\n}\n```\n\n**OUTPUT:**\n\n```kotlin\nUser(id=1, name=Dunn)\nUser(id=2, name=Sue)\n```\n\nAlthough Kotlin seems to have lost in this example by being wordier and resorting to Lists, hold on. Kotlin has no direct concept of [generators](https://wiki.python.org/moin/Generators) and `yield` keywords. However, we can accomplish something that fulfills the same purpose (and is arguably stylistically better) through `Sequence`.\n\n```kotlin\nfun main(args: Array) {\n \n data class User(val id: Int, val name: String)\n \n val users = listOf(\n User(0,\"Hero\"),\n User(1, \"Dunn\"),\n User(2, \"Sue\"),\n User(3, \"Chi\"),\n User(4, \"Thor\"),\n User(5, \"Clive\"),\n User(6, \"Hicks\"),\n User(7, \"Devin\"),\n User(8, \"Kate\"),\n User(9, \"Klein\")\n )\n \n \n val friendships = listOf(\n 0 to 1, 0 to 2, 1 to 2, 1 to 3, 2 to 3, 3 to 4,\n 4 to 5, 5 to 6, 5 to 7, 6 to 8, 7 to 8, 8 to 9\n )\n \n fun userForId(id: Int) = users.asSequence().filter { it.id == id }.first()\n \n fun friendsOf(user: User) = friendships.asSequence()\n .filter { it.first == user.id || it.second == user.id }\n .flatMap { sequenceOf(it.first,it.second) }\n .filter { it != user.id }\n .map { userForId(it) }\n \n fun mutualFriendsOf(user: User, otherUser: User) = friendsOf(user).flatMap { friend ->\n friendsOf(otherUser).filter { otherFriend -> otherFriend.id == friend.id }\n }\n \n mutualFriendsOf(users[0],users[3]).forEach { println(it) }\n}\n```\n\n**OUTPUT:**\n\n```\nUser(id=1, name=Dunn)\nUser(id=2, name=Sue)\n```\n\nWe can use the `Sequence` to compose a series of operators as a chain, like `filter()`, `map()`, `flatMap()`, and many others. This style of functional programming has been getting a lot of traction over the past few years, primarily because it easily breaks up logic into simple pieces and increases maintainability. 99.99% of the time, I am never using `for` loops but rather using a Kotlin `Sequence`, a Java 8 `Stream`, or an RxKotlin/RxJava `Observable`. This chain-operator syntax is becoming less alien in Python as well (look at [PySpark](http://www.mccarroll.net/blog/pyspark/) and [RxPy](https://github.com/ReactiveX/RxPY)). What is great about this style of programming is you can read what is happening left-to-right, top-to-bottom rather than jumping through several loops and helper functions.\n\n## Conclusions\n\nIn the coming months, I am going to blog about my experiences using Kotlin for data science, and I will continue to share what I learn. I may throw in an article occasionally covering [ReactiveX](http://reactivex.io/) for data science as well (for both Kotlin and Python). I acknowledge that the Java JVM platform, which Kotlin runs on, does not handle numbers as efficiently as Python or R (maybe [Project Valhalla will change that?](http://openjdk.java.net/projects/valhalla/)). But successful models inevitably need to turn into execution, and the Java platform increasingly seems to be the place that happens.\n\nKotlin merely provides a pragmatic abstraction layer that provides a tactical and concise syntax that seems excellent for data analysis. Not to mention, Kotlin has spurred many powerful open-source libraries even before a year after its release. One library, [TornadoFX](https://github.com/edvin/tornadofx), allows rapid turnaround of complex business user interfaces using Kotlin (As a disclaimer, I have helped with TornadoFX as well as [RxKotlinFX](https://github.com/thomasnield/RxKotlinFX)). The Kotlin community is incredibly active, growing, and engaged on the [Slack channel](http://kotlinslackin.herokuapp.com/). It [continues to be adopted on Android](https://www.raywenderlich.com/132381/kotlin-for-android-an-introduction), and JetBrains is using Kotlin to build all their tools (including PyCharm and Intellij IDEA). It is also [replacing Groovy as the official language for Gradle](https://blog.gradle.org/kotlin-meets-gradle). Because of these facts, I do not see Kotlin's momentum slowing down anytime soon.\n\nI believe Kotlin could make a great first JVM language, more so than Java or Scala. There is a new [O'Reilly video series](http://shop.oreilly.com/product/0636920052982.do) that covers Kotlin from scatch, and its instructor Hadi Hariri (one of the JetBrains folks behind Kotlin) believes Pythonistas should be able to follow along. He said anybody familiar with classes, functions, properties, etc should be able to learn Kotlin in a day with this video series. Unfortunately, the existing [Kotlin documentation](https://kotlinlang.org/docs/reference/) and [books](https://www.manning.com/books/kotlin-in-action) assume prior Java knowledge, and hopefully more resources other than the video pop up in the future.\n\nThere is a lot of exciting features I have not covered about Kotlin in this article. Features like [nullable types](https://kotlinlang.org/docs/reference/null-safety.html), [extension properties and functions](https://kotlinlang.org/docs/reference/extensions.html), and [boilerplate-free delegates](https://kotlinlang.org/docs/reference/delegation.html) make the language pleasant to use and highly productive. So check out Kotlin if you are using Python or Scala for data science. I will continue blogging about my experiences, and showcase it being used in deeper data science topics as well as Spark.\n\n","author":"Thomas Nield","date":"2016-10-28","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Android development with Kotlin","url":"http://inaka.net/blog/2016/01/15/android-development-with-kotlin/","body":"\n\n## What is Kotlin?\n\n[Kotlin](https://kotlinlang.org/) is a statically typed programming language for the Java Virtual Machine, Android and web browsers. Inside Android apps we can use Kotlin language to replace Java code, but also we can use both together having Java classes and Kotlin classes in the same project.\n## Getting started\n\nUsing Android Studio\n\n### 1. Install the Kotlin plugin\n\nGo to \"Android Studio\" menu, \"Preferences\", \"Plugins\", search 'Kotlin' and install the plugin. Then you will have to restart Android Studio.\n\n### 2. Start a new Android project\n\nLet's create a new Android project: go to \"Start a new Android Studio project\" or \"File\" menu, and click \"New project\".\n\n### 3. Configure gradle\n\nYou can configure Kotlin in the project by clicking \"Help\" on the menu, then \"Find Action\" (or press ⇧⌘A) and finally enter \"Configure Kotlin in Project\". Then you should choose the Kotlin version that you want. After that, the app/build.gradle file should be updated. Also, instead of using \"Find Action\", you can edit the app/build.gradle file manually. Here is an example:\n\n\n```groovy\napply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\n\nandroid {\n compileSdkVersion 23\n buildToolsVersion \"23.0.2\"\n\n defaultConfig {\n applicationId \"examples.kotlin.inaka.com\"\n minSdkVersion 17\n targetSdkVersion 23\n versionCode 1\n versionName \"1.0\"\n }\n buildTypes {\n release {\n minifyEnabled false\n proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n }\n }\n sourceSets {\n main.java.srcDirs += 'src/main/kotlin'\n }\n}\n\nbuildscript {\n ext.kotlin_version = '1.0.0-beta-4583'\n repositories {\n mavenCentral()\n }\n dependencies {\n classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n classpath \"org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version\"\n }\n}\n\nrepositories {\n mavenCentral()\n}\n\ndependencies {\n compile fileTree(dir: 'libs', include: ['*.jar'])\n compile 'com.android.support:appcompat-v7:23.1.1'\n compile \"org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version\"\n}\n```\n\n### 4. Convert .java to Kotlin (.kt) files\n\nOpen a Java file and choose \"Help\" on the menu, then \"Find Action\" (or press ⇧⌘A) and enter the action \"Convert Java File to Kotlin File\". Alternatively you can call this option via \"Code\" menu, \"Convert Java File to Kotlin File\".\n\n## Some characteristics\n\nUsing Kotlin to develop Android apps introduce many differences and 'advantages' compared to Java development. Here I will mention some of them:\n\n### Variables and type inference\n\n```kotlin\nvar age = 5 // you don't need to declare as an Int\n```\n\nBut if you want to declare the type:\n\n```kotlin\nvar age: Int = 5\n```\n\nJava's 'final' = Kotlin's 'val':\n\n```kotlin\nval name = \"Fernando\" // 'val' can't be reassigned\n```\n\n### Pattern matching\n\n```kotlin\nfun valueDependingOnType(type: Int) {\n var value = 0\n when (type) {\n 1 -> toast(value.toString())\n 2 -> {\n value = 100\n toast(value.toString())\n }\n else -> toast(type.toString())\n }\n}\n```\n\n### Safe call - null verification\n\nVerifying null object with Java:\n\n```kotlin\nint len;\nif(list != null){\n len = list.size();\n}\n```\n\nSame as above but using Kotlin language:\n\n```kotlin\nvar len = list?.size\n```\n\nSafe cast example:\n\n```kotlin\nval x: String? = y as? String\n\n```\n\n### Properties\n\nAvoid usage of getters and setters:\n\n```kotlin\nvar user = User()\nuser.name = \"Fernando\" // set user's name\ntoast(user.name) // get user's name\n```\n\n### Companion object\n\nA Kotlin class can have a companion object. This is like the static variable for Java classes. For example:\n\n```kotlin\nclass MainActivity : AppCompatActivity() {\n\n companion object {\n val PICK_CONTACT = 100\n }\n\n ...\n}\n```\n\nThen you can call MainActivity.PICK_CONTACT and it will receive the value 100.\n\n### String templates\n\n```kotlin\nfun printFirst(array: Array) {\n if (array.size == 0) return\n print(\"First value: ${array[0]}\")\n}\n```\n\n### Ranges\n\n```kotlin\nif (x in 1..y)\nprint(\"x is >= 1 and <= y\")\n```\n\n### Lambda expressions\n\n```kotlin\nfun foo(numbers: ArrayList) {\n val doubled = numbers.map { elem -> elem * 2 }\n ...\n}\n```\n\nor\n\n```kotlin\nfun foo(numbers: ArrayList) {\n val doubled = numbers.map { it * 2 }\n ...\n}\n```\n\n### Kotlin extensions - finding views\n\nYou don't need to call the findViewById() method. For example, if you want to change programatically the text of a TextView with id \"textView1\" from activity_main.xml you can do:\n\n```kotlin\nimport kotlinx.android.synthetic.main.activity_main.*\n```\n\nAnd then into onCreate method:\n\n```kotlin\ntextView1.text = \"example text\"\n```\n\n## Resources\n\n[Kotlin language official documentation](https://kotlinlang.org/docs/reference/)\n\n### Some open source example projects\n\n* [kotlillon](https://github.com/inaka/kotlillon) Compilation of simple Kotlin examples, all together in one Android app\n* [restful_android_kotlin](https://github.com/ramabit/restful-android-kotlin) Restful Android app example, using Kotlin with Realm, Retrofit, Picasso, Robospice and more\n\n### Some interesting Kotlin libraries for Android development\n\n* [Anko](https://github.com/Kotlin/anko)\n* [RxKotlin](https://github.com/ReactiveX/RxKotlin)\n* [kotterknife](https://github.com/JakeWharton/kotterknife)\n* [kotlin-nosql](https://github.com/cheptsov/kotlin-nosql)\n\n","author":"Fernando Ramirez","date":"2016-01-15","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Our first book about Kotlin is out","url":"https://blog.jetbrains.com/kotlin/2017/02/our-first-book-about-kotlin-is-out/","body":"\nWe’re happy to announce that [Kotlin in Action][] – a book about Kotlin written by the members of the Kotlin team – is now out, as both a eBook and a printed book. The book is written for experienced Java developers and covers all aspects of the language, without focusing on any specific problem domain. We received a lot of positive feedback about the book during Manning’s Early Access Preview program, so we hope that you’ll enjoy it too!\n\n![Kotlin in Action book][]\n\n\nTwo chapters from the book, covering Kotlin’s type system and its support for domain-specific languages, are available as a [free preview][] on the publisher’s Web site. And in our online mini-IDE for Kotlin, you can try out all examples from the book, starting from the [very first one][], also for free.\n\nTo accompany the release of the book, Manning is offering a special discount, valid today only: you can get half off the book if you enter the code *dotd021017au* during checkout.\n\nHappy reading, and have a nice Kotlin!\n\n\n[Kotlin in Action]: https://www.manning.com/books/kotlin-in-action\n[Kotlin in Action book]: https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2017/02/20170209_112611.jpeg\n[free preview]: https://www.manning.com/books/kotlin-in-action#downloads\n[very first one]: http://try.kotlinlang.org/#/Kotlin%20in%20Action/chapter%201/1.1/1.1_ATasteOfKotlin.kt\n","author":"Dmitry Jemerov","date":"2017-02-10","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Scala vs Kotlin: Operator overloading","url":"https://blog.frankel.ch/scala-vs-kotlin/2/","body":"\nLast week, I started my comparison of Scala and Kotlin with the [Pimp my library](/scala-vs-kotlin/1/) pattern. In the second part of this serie, I’d like to address operator overloading.\n\n## Overview\n\nBefore to dive into the nitty-gritty details, let’s try first to tell what it’s all about.\n\nIn every language where there are functions (or methods), a limited set of characters is allowed to define the name of said functions. Some languages are more lenient toward allowed characters: naming a function `\\O/` might be perfectly valid.\n\nSome others are much more strict about it. It’s interesting to note that Java eschewed the ability to use symbols in function names besides `$` - probably in response to previous abuses in older languages. It definitely stands on the less lenient part of the spectrum and the Java compiler won’t compile the previous `\\O/` function.\n\nThe name operator overloading is thus slightly misleading, even if widespread. IMHO, it’s semantically more correct to talk about operator characters in function names.\n\n## Scala\n\nScala stands on the far side of leniency spectrum, and allows characters such as `+` and `£` to be used to name functions, alone or in combinations. Note I couldn’t find any official documentation regarding accepted characters (but some helpful discussion is available [here](https://stackoverflow.com/questions/7656937/valid-identifier-characters-in-scala)).\n\nThis enables libraries to offer operator-like functions to be part of their API. One example is the `foldLeft` function belonging to the `TraversableOnce` type, which is also made available as the `/:` function.\n\nThis allows great flexibility, especially in defining DSLs. For example, mathematics: functions can be named `π`, `∑` or `√`. On the flip side, this flexibility might be subject to abuse, as `\\O/`, `^_^` or even `|-O` are perfectly valid function names. Anyone for an emoticon-based API?\n\n```scala\ndef ∑(i: Int*) = i.sum\n\nval s = ∑(1, 2, 3, 5) // = 11\n```\n\n## Kotlin\n\nKotlin stands on the middle of the leniency scale, as it’s possible to define only a [limited set of operators](https://kotlinlang.org/docs/reference/operator-overloading.html).\n\nEach such operator has a corresponding standard function signature. To define a specific operator on a type, the associated function should be implemented and prepended with the `operator` keyword. For example, the `+` operator is associated with the `plus()` method. The following shows how to define this operator for an arbitrary new type and how to use it:\n\n```kotlin\nclass Complex(val i: Int, val j: Int) {\n operator fun plus(c: Complex) = Complex(this.i + c.i, this.j + c.j)\n}\n\nval c = Complex(1, 0) + Complex(0, 1) // = Complex(1, 1)\n\n```\n\n## Conclusion\n\nScala’s flexibility allows for an almost unlimited set of operator-looking functions. This makes it suited to design DSL with a near one-to-one mapping between domains names and function names. But it also relies on implicitness: every operator has to be known to every member of the team, present **and** future.\n\nKotlin takes a much more secure path, as it allows to define only a limited set of operators. However, those operators are so ubiquitous that even beginning software developer know them and their meaning (and even more so experienced ones).\n\n","author":"Nicolas Fränkel","date":"2016-07-24","type":"article","categories":["Kotlin","Scala"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Functional Programming in Kotlin with funKTionale (Video)","url":"https://www.youtube.com/watch?v=klakgWp1KWg","body":"\n\n[Slides](https://speakerdeck.com/marioariasc/functional-programming-in-kotlin-with-funktionale-2)\n\n\n\n","author":"Mario Arias","date":"2016-12-16","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"DevZen Podcast: Kotlin и Vulkan 1.0 — Episode 0080.","url":"http://devzen.ru/episode-0080/","body":"\nТемы выпуска: Сравнение разных конфигурации сети в Kubernetes, Kotlin наконец вышел в версии 1.0, Vulkan тоже вышел в 1.0, критическая уязвимость в glibc, ZFS в Ubuntu 16.04, снова Rust, и про Монады. И, конечно, ответы на вопросы слушателей.\n\nШоу нотес:\n\n* Вакансия C++ & Scala Software Engineer\n* Comparison of Networking Solutions for Kubernetes — Comparison of Networking Solutions for Kubernetes 2 documentation\n* [Kotlin 1.0 Released: Pragmatic Language for JVM and Android | Kotlin Blog](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/)\n* Go 1.6 is released — The Go Blog\n* Does FreeBSD support OpenGL 3.3?\n* Unable to build Assimp on FreeBSD 10.2 · Issue #795 · assimp/assimp · GitHub\n* Vulkan — Industry Forged\n* Vulkan in 30 minutes\n* OpenNews: Опубликован графический стандарт Vulkan 1.0\n* Khronos Products\n* Vulkan 1.0 Released: What You Need To Know About This Cross-Platform, High-Performance Graphics API — Phoronix\n* PVS-Studio покопался в ядре FreeBSD\n* Критическая уязвимость библиотеки glibc позволяет осуществлять удаленное выполнение кода / Блог компании Positive Technologies / Хабрахабр\n* FreeBSD and CVE-2015-7547\n* OpenNews: В Ubuntu 16.04 будет добавлена поддержка ZFS и Vulkan\n* From the Canyon Edge: ZFS is *the* FS for Containers in Ubuntu 16.04!\n* There is No Now — ACM Queue\n* select * from depesz; » Blog Archive » Waiting for 9.6 – Remove GROUP BY columns that are functionally dependent on other columns.\n* Hint Bits — PostgreSQL wiki\n* Speeding up things with hint bits — Cybertec — The PostgreSQL Database Company\n* Introduction to Windows shellcode development – Part 3 – Security Café\n* The latest high-end Ubuntu phone will be available globally | ZDNet\n* CharybdeFS: a new fault-injecting filesystem for software testing\n* Red Book, 5th ed. Ch. 6: Weak Isolation and Distribution\n* PostgreSQL: Documentation: 9.5: Transaction Isolation\n* [Libevent-users] Comparison of libevent and libuv\n* Kazuho’s Weblog: The reasons I stopped using libuv for H2O\n* Using non-blocking and asynchronous I/O (CK10 problem) in Linux and Windows (with epool, iocp, libevent/libev/libuv/boost.asio and librt/libaio) | Rui’s Blog\n* Запах монад по утрам — Прогулки по воде\n* Темы и вопросы слушателей для 0080 « DevZen Podcast\n\n","author":"DevZen Podcast","date":"2016-02-20","type":"article","categories":["Podcast","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":{"url":"http://devzen.ru/download/2016/devzen-0080-2016-02-19-3280e712a2cc1485.mp3","size":55240704}},{"title":"Kotlin: A Low-Ceremony, High-Integration Language","url":"http://www.oracle.com/technetwork/issue-archive/2015/15-sep/index.html","body":"\nWork with a statically typed, low-ceremony language that provides first-class functions, nullability protections, and complete integration with existing Java libraries.\n\nIt has been more than five years since Project Kotlin, an open source language targeting the JVM, was announced by JetBrains. Since then, much progress has been made, some language designs have changed, a new platform — namely JavaScript — is now supported, and even the project name has changed. It’s now simply known as Kotlin. But if there’s one thing that still remains, it is the initial goals and intent for why Kotlin was developed.\n\nAt JetBrains, we have been developing IDEs for many programming languages, and yet despite this, much of our code continues to be written in Java. In 2009, we were looking for an alternative to Java, something that could reduce the size of our codebase by being more concise and, at the same time, offer features that we felt could provide important benefits. We needed a language that was also syntactically similar enough to Java that ramp-uptime would not be substantial. The main contender at the time was Scala, but the compiler performance wasn’t that great and providing tooling for Scala was (and continues to be) quite challenging. Tooling and performance were important aspects in our decision, so we opted not to go with Scala. Thus was born Project Kotlin.\n\nShortly afterward, news about the JVM language Ceylon was announced; and at one point we considered joining efforts. However, at the time, Ceylon’s focus on interoperability was somewhat of a low priority. Given that we have a large codebase in Java, being able to use and extend it was of considerable importance to us. Thus, we decided to continue down our own path with Kotlin.\n\n## Removing the Pain\n\nFive years later and close to reaching the 1.0 milestone, Kotlin remains true to its initial goals of being concise, safe, interoperable, “toolable”, and performant. Many, if not all, of these goals are for a single purpose: removing some of the pain and the errors we encounter when writing code.\n\nThe IntelliJ platform is an extremely large codebase on which all our IDEs, including IntelliJ IDEA, are built. The open source Community Edition alone, which is hosted on [GitHub](https://github.com/JetBrains/intellij-community/), has millions of lines of code. While there is a lot of functionality, much of the code is often boilerplate code that is necessary because, well, because it’s Java. One of Kotlin’s goals has been to reduce the amount of somewhat pointless code yet maintain readability and functionality. For instance, a typical Java bean with property getters, setters, toString, and equality in Kotlin can be reduced to the following:\n\n```kotlin\ndata class Customer(\n var name: String,\n var email: String\n)\n```\n\nThings such as smart-casting remove the need for verbosity by delegating the work to the compiler. For example, when checking an immutable value for a specific type, it’s no longer necessary to cast to that type when operating on it:\n\n```kotlin\nfun convert(obj: Shape) {\n if (obj is Circle) {\n val radius = obj.radius()\n // ...\n }\n}\n```\n\nKotlin also has support for named objects, which, in essence, means a singleton would simply be written as follows:\n\n```kotlin\nval MySingleton = object {\n val numberOfDays = 10\n}\n```\n\nAnother pain point Kotlin addresses is the need to use functional constructs — such as lambda expressions and higher-order functions — and to treat functions as first-class citizens. While Java 8 addresses some of these concerns, our goal was and continues to be to provide this functionality when using Java 6, 7, or 8 — thus, even allowing support for these features on the Android platform. This is one reason that Kotlin has enjoyed considerable popularity in the Android development community.\n\nFunctions can be top-level in Kotlin, much like they are in JavaScript, meaning there’s no need to attach a function to an object. As such, we could simply declare a function in a file like this:\n\n```kotlin\nfun toSentenceCase(input: String) {\n // ...\n}\n```\n\nMuch like C#, Kotlin also allows extension functions, meaning a type (either of Java or Kotlin) can be extended with new functionality simply by suffixing the type. Taking the previous example, if I want the String type to have `toSentenceCase()`, I can simply write the following:\n\n```kotlin\nfun String.toSentenceCase() {\n // 'this' would hold an\n // instance of the object\n}\n```\n\nTo work efficiently with functions as primitives, there needs to be support for higher-order functions — that is, functions that take functions as parameters or return functions. With Kotlin, this is possible, for example:\n\n```kotlin\nfun operate(x: Int, y: Int, operation: (Int, Int) -> Int) {\n // ...\n}\n```\n\nThis code declares a function that takes three parameters: two integers and a third parameter that is a function that, in turn, takes two integers and returns an integer. We can then invoke functions as follows:\n\n```kotlin\nfun sum(x: Int, y: Int) {\n // ...\n}\n\noperate(2, 3, ::sum)\n```\n\nThis code shows a function, `sum`, being defined and passed as a parameter to operate. It shows that Kotlin supports referencing functions by name. Of course, a lambda expression can be passed in as well:\n\n```kotlin\noperate(2, 3, { x, y -> x +y })\n```\n\nThese capabilities deliver an elegant way of doing function pipelining:\n\n```kotlin\nval numbers = 1..100\n\nnumbers\n .filter { it % 2 == 0 }\n .map { it + 5 }\n .forEach {\n println(it)\n }\n```\n\nOne more issue we attack with Kotlin is null pointer exceptions. In Kotlin, by default, things cannot be null, meaning that potentially the only way we’d get a null reference exception would be if we explicitly force it.\n\n```kotlin\nvar city = \"London\"\n```\n\nIn the code above, city could never be assigned a null value. If we want it to be null, we need to go out of our way to be explicit:\n\n```kotlin\nvar city : String? = null\n```\n\nwhere `?` indicates that a type can be nullable. When interoperating with Java, we provide certain mechanisms to warn of possible null references, as well as providing some operators to make the code more concise, such as the safe call operator:\n\n```kotlin\nvar file = File(\"...\")\nfile?.length()\n```\n\nBecause of the `?.` , this code would invoke `length()` on `file` only if `file` were not `null`. The standard library, a small runtime that ships with Kotlin, also provides additional functions in this area, such as the `let` function, which when combined with the safe call operator allows for succinct code, such as the following:\n\n```kotlin\nobj?.let {\n... // execute code here\n}\n```\n\nThis results in the code block executing if the object is not null.\n\nOne last thing worth mentioning about Kotlin is its ability to easily enable the creation of DSLs — without the overhead that necessarily comes with maintaining them or the language knowledge required to implement them. Top-level functions, higher-order functions, extension functions, and a few conventions, such as not having to use brackets when the last parameter to a function is another function — these features allow for creating rich DSLs that are strongly typed. The quintessential example is that of type-safe Groovy-style builders. The following function generates the expected HTML output:\n\n```kotlin\nhtml {\n head {\n title { +\"XML encoding with Kotlin\" }\n }\n body {\n h1 { +\"XML encoding with Kotlin\" }\n p { +\"this is an alternative markup to XML\" }\n }\n}\n```\n\n## Growth and the Road Ahead\n\nThe previous code snippets are just a few examples of what Kotlin provides. It wouldn’t be possible to cover all the little details and conveniences Kotlin offers in a single article.\n\nOver the past year, and despite not having released version 1.0, we’ve noticed a substantial growth and interest in Kotlin. There has been an increase in downloads and visits to the Kotlin site, as well as an increase in technical questions in both our forums and public venues such as StackOverflow.\n\nWhile a lot of this interest is due to the Android community and our contributions in terms of additional tooling and frameworks for this space, there’s also interest in other more generic areas such as web development, both client-side (given Kotlin’s ability to compile to JavaScript) and server-side.\n\nWe’re close to reaching the first major release, and we’ve made significant steps toward that. Over the past few milestone releases, we’ve been removing and adjusting some things in the language to make sure that once we release, we’ll be fairly certain that what we ship is there to stay. As any language designer or developer knows, whatever goes in a language stays as baggage pretty much forever.\n\nAs a company that provides tooling for developers, we’ve tried to make language release transitions as smooth as possible. To this end, a new release usually comes with a compiler warning about a potential upcoming change or deprecation. The IDE also provides a quick fix to easily migrate code to newer syntax. We believe that this way, we create a smooth experience for developers that are already using Kotlin in production.\n\nBeyond these quick fixes, we’re also focusing on improving other aspects of tooling. For Kotlin to be successful, the entry barrier should be low in all aspects. That is why we not only provide tooling for IntelliJ IDEA, in both Ultimate and the open source Community Edition, but also for build tools such as Gradle, Ant, and Maven, as well as a simple command-line compiler. We’ve also released a preliminary version of Kotlin for Eclipse, and we’re hoping that much like there are contributions to Kotlin in other areas, the community will contribute to Eclipse support as well.\n\n## Conclusion\n\nIn conclusion, we developed Kotlin for our own use primarily and are heavily invested in it. For us, it’s a tool that we’re using to drive our own business, which is developer tools. We already have several internal and public-facing web applications written in Kotlin. Some of our newer tools are being written in Kotlin and our existing tools, such as IntelliJ IDEA and YouTrack, are adopting Kotlin. `
    `\n\n> This article is the inaugural installment of a new series on JVM languages that will appear in Java Magazine. We will examine the full range of languages, from large commercial efforts to projects driven by determined groups of hackers. In the next issue, we’ll cover Jython. —Ed.\n\n## LEARN MORE\n* [Kotlin home](http://kotlinlang.org/)\n* [Kotlin on StackOverflow](https://stackoverflow.com/questions/tagged/kotlin)\n* [Kotlin on Reddit](https://www.reddit.com/r/Kotlin/)\n","author":"HADI HARIRI","date":"2015-09-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Exploring Delegation in Kotlin","url":"http://codemonkeyism.com/exploring-delegation-in-kotlin/","body":"\nI’m a huge fan of interfaces in Java and also of composition over inheritance. Inheritance is some magic wiring with tight coupling that creates lots of friction when evolving a code base. I’ve written about interfaces before several times, for example [here](http://codemonkeyism.com/how-to-improve-programming-with-interfaces/) or [here](http://codemonkeyism.com/generation-java-programming-style/). Looking at Kotlin I wanted to see what I can do with interfaces and composition.\n\nTake this example:\n\n```kotlin\ninterface HasName {\n fun getName():String\n}\n\nclass Person(): HasName {\n override fun getName():String = \"Stephan\"\n}\n\nfun main(args: Array) {\n val p = Person()\n // Prints 'Stephan'\n println(p.getName())\n}\n\n```\n\nWhy would one introduce a `HasName` interface in this case? It reduces dependencies and coupling. This makes reasoning about code easier and speeds up compilation, especially incremental compilation.\n\nHow would we use the `HasName` interface? A function that checks for a good name could look like this:\n\n```kotlin\nfun goodName(p:Person):Boolean {\n return p.getName() == \"Stephan\"\n}\n```\n\nNow the function depends on the whole of person, not just the name part. The function can not operate on a lot of things, just persons. What about other things with `Name`, like Dogs? Rewritting the code to\n\n```kotlin\nfun goodName(n:HasName):Boolean {\n return n.getName() == \"Stephan\"\n}\n```\n\nmakes the function more reusable.\n\nInside our `Person class` we have the code for the `HasName` functionality. It woud be nicer to be able to reuse the functionality from somewhere else.\n\nIn Kotlin we can delegate Interfaces to objects:\n\n```kotlin\ninterface HasName {\n fun getName():String\n}\n\nclass NameMixin(val n:String): HasName {\n override fun getName() = n\n}\n\nclass Person(n:NameMixin): HasName by n {\n}\n\nfun main(args: Array) {\n val p = Person(NameMixin(\"Stephan\"))\n // Prints 'Stephan'\n println(p.getName())\n}\n\n```\n\nThis looks a little unnatural to me, as the user of the `Person class` needs to know about the `NameMixin`. See if we can do better\n\n```kotlin\nclass Person(n:String): HasName by NameMixin(n) {\n}\n\nfun main(args: Array) {\n val p = Person(\"Stephan\")\n // Prints 'Stephan'\n println(p.getName())\n}\n\n```\n\nlooks cleaner as the consumer of `Person` does not know about `NameMixin`.\n\nKotlin can also use data classes (Thanks to Christian Helmbold for pointing this out).\n\n```kotlin\ninterface HasName {\n val name: String\n}\n\ndata class NameMixin(override val name: String) : HasName\n\nclass Person(named : HasName) : HasName by named\n```\n\nIf we want to have more control, we can use a Factory inside `Person`.\n\n```kotlin\nclass Person(n:String): HasName by Person.name(n) {\n companion object Name {\n fun name(n:String) = NameMixin(n)\n }\n}\n\n```\n\nThe name of the `companion object`, in this case `Name`, is optional but helps to structure the factory methods.\n\nThe mixin can be accessed with `this`:\n\n```kotlin\nclass Person(n:String): HasName by Person.name(n) {\n ...\n fun isStephan():Boolean {\n // Access name property\n return this.getName() == \"Stephan\"\n }\n}\n```\n\nUsing a `companion object` with a factory method is better, because it gives us more control in the creation of the Mixin. But the control is not optimal. I wish we had something like\n\n```kotlin\n// Not working Kotlin code!\nclass Person(n:String): HasName {\n val name delegates from HasName\n}\n```\n\nwhere I have access to name and more control over it. It would also be nice to have a way to access other Mixins from a Mixin. But overall, some nice functionality in Kotlin.\n\n","author":"@codemonkeyism","date":"2016-04-04","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Zero boilerplate delegation in Kotlin","url":"https://medium.com/@piotr.slesarew/zero-boilerplate-delegation-in-kotlin-e383fdef28eb#.k4sdth6d4","body":"\n![](https://cdn-images-1.medium.com/max/880/1*40AToH3O5szPdLfWU3kLVA.jpeg)\n\n> Delegation is an implementation mechanism in which an object forwards or delegates a request to another object. — _(_[_GoF_](https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented-ebook/dp/B000SEIBB8)_)_\n\nIt is said that [inheritance](https://en.wikipedia.org/wiki/Inheritance_%28object-oriented_programming%29) is useful only in case of having [Donald Trump](https://en.wikipedia.org/wiki/Donald_Trump) as a father. Abstract classes have a lot of gotchas in term of designing scalable and reusable architecture. How many times did you create the superclass in your codebase that could not be replaced and blocked you from doing new fancy features? Thanks to [Henry Lieberman](https://g.co/kgs/EzZ2yF) our programming toolbox include an amazing delegation_,_ so it can be used against wrong abstractions. Remember! The wrong abstraction is worst than no abstraction.\n\nWords are cheap, let’s code a little bit.\n\n```kotlin\nclass CopyPrinter implements Copy, Print {\n\n private Copy copier;\n private Print printer;\n\n public CopyPrinter(Copy copier, Print printer) {\n this.copier = copier;\n this.printer = printer;\n }\n\n @Override\n public Page copy(Page page) {\n return copier.copy(page);\n }\n\n @Override\n public void print(Page page) {\n printer.print(page);\n }\n}\n\ninterface Copy {\n Page copy(Page page);\n}\n\ninterface Print {\n void print(Page page);\n}\n\nclass Page {}\n```\n\nThe sample above is pretty straightforward, but still begging for some code generation because of having boilerplate in it. It would be so nice to have delegation as a built-in language feature. In old Java world things like that does not exist, so is there any way to solve that problem differently? It is possible to use annotation processing to create a library for code generation or implement reflection to invoke methods dynamically. That sounds pretty scary, right? As a fan of [Kotlin](https://kotlinlang.org), I will show you how to delegate like a pro.\n\n### [Kotlin](https://kotlinlang.org)\n\nAs I have already mentioned, there is a huge need of having delegationpattern implemented in language. Guess what! [Kotlin](https://kotlinlang.org) has it❤.\n\n```kotlin\nclass CopyPrinter(copier: Copy, printer: Print) : Copy by copier, Print by printer\n\ninterface Copy {\n fun copy(page: Page): Page\n}\n\ninterface Print {\n fun print(page: Page)\n}\n\nclass Page\n```\n\nJust amazing. When I saw it for the first time it literally blew my mind. [Kotlin](https://kotlinlang.org) makes it so clear and concise that I do not have to explain what the code does.\n\nAnd if that is not enough, [Kotlin](https://kotlinlang.org) have the whole concept of [Delegated Properties](https://kotlinlang.org/docs/reference/delegated-properties.html). If you are not familiar with it, you have to read it and start using it as soon as possible.\n\n> Any piece of code that you’re forced to duplicate or that can be automatically generated by an IDE is a missing language abstraction feature. — ([**Mario Fusco**](https://twitter.com/mariofusco/status/790171082242359296))\n\n#### Notes:\n\n[GoF](https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented-ebook/dp/B000SEIBB8), [Delegated Properties](https://kotlinlang.org/docs/reference/delegated-properties.html), [Kotlin](https://kotlinlang.org), [Henry Lieberman](https://g.co/kgs/EzZ2yF)\n\n","author":"Piotr Ślesarew","date":"2016-10-28","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin null safety and its performance considerations -- part 1","url":"http://allegro.tech/2016/06/kotlin-null-safety-part1.html","body":"\n[Kotlin](http://kotlinlang.org) may seem like a new kid on the block – itʼs been officially released only in [February](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/). Its history however dates [a few years back](http://www.infoworld.com/article/2622405/java/jetbrains-readies-jvm-based-language.html) and itʼs mature and stable enough to be used for developing solid reliable applications. Therefore at [Allegro](http://allegro.pl) we decided to give it a chance – we built our new shiny server-side system using Kotlin as its primary language and we do not regret it.\n\nOne of the first features a Kotlin developer learns is the languageʼs approach to handling `null` values. It is quite interesting – especially at times like these when the most popular way of handling this problem is to use some kind of [Option monad](https://en.wikipedia.org/wiki/Option_type). As weʼll soon see Kotlin actually does not introduce any new special wrapper type – it uses regular Java types albeit with slight variance.\n\n## Null-safe world\n\nIn Kotlin when you declare a variable, a field or a function parameter, by default they cannot be `null`. For example letʼs suppose we have a class `Greeter` which has a function `hello` that by default prints a greeting message on the standard output:\n\n```kotlin\nclass Greeter {\n fun hello(who: String): Unit {\n println (\"Hello $who\")\n }\n}\n```\n\nWe declared `who` to be of type `String` which is interpreted by the compiler to mean that `who` cannot be `null`. If we want to declare a _nullable_ parameter we have to add a question mark at the end of the type name:\n\n```kotlin\nclass Greeter {\n fun hello(who: String?): Unit {\n println (\"Hello $who\")\n }\n}\n```\n\nThis simple solution turns out to be very convenient and strong at the same time. It divides the world of our code into two areas: one where `null`s are allowed and one where they arenʼt. As weʼll see in a moment Kotlin provides quite a range of helpful features which makes the transition between those areas entirely safe. Yet we have to be aware of a few surprising issues.\n\nTo fully explore how Kotlin handles `null`s underneath weʼll take a closer look at the code generated by Kotlin compiler. Weʼll do it on two levels: first weʼll inspect the output bytecode – although for brevity weʼll actually see equivalent Java code. Then, in the second part of this article – for some interesting cases weʼll have a glance at the machine code generated by [JVM JIT compiler](http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html#JITCompilers).\n\n### Smart casts\n\nSince Kotlin compiler knows the type of every variable, field, function parameter, etc. it can check if an incorrect assignment takes place and throw an error in such case. In the code below we try to assign a _nullable_ reference to a _non-null_ property:\n\n```kotlin\nclass User {\n private var username: String = \"\"\n\n fun setName(newName: String?) {\n username = newName // the compiler will indicate an error here\n }\n}\n```\n\nWhat if we wanted to check if the reference is not `null` and only then assign it to a property? The following code provides an answer:\n\n```kotlin\nclass User {\n private var username: String = \"\"\n\n fun setName(newName: String?) {\n if (newName == null)\n throw NullPointerException(\"Name cannot be null!\")\n\n username = newName // here the compiler knows that newName cannot be null and therefore\n } // its type is String and not String?\n}\n```\n\nThis construct – where the compiler can infer that the reference cannot be `null` – is called smart casting as it seems to cast the reference from `String?` to `String`.\n\nThere is one thing we have to bear in mind when using smart casts. We can only do it with references that cannot be changed between the checkpoint and the actual assignment. In the code above the reference was taken from the function parameter which cannot change in the course of function execution. If we were to take the reference from some read/write property the compiler would not allow it:\n\n```kotlin\nclass UserRequest {\n var username: String? = null\n}\n\nclass User {\n private var username: String = \"\"\n\n fun setNameFrom(request: UserRequest) {\n if (request.username == null)\n throw NullPointerException(\"Name cannot be null!\")\n\n username = request.username // here the compiler cannot be sure that request.username\n } // is not null - it could change in some other thread\n} // right after the condition check\n```\n\n### The !! operator\n\nThe code shown in the above example looks quite common. When we expect a reference to be not `null` and this assumption proves wrong we may want to throw `NullPointerException`. Kotlin has a special syntax for such cases:\n\n```kotlin\nclass User {\n private var username: String = \"\"\n\n fun setName(newName: String?) {\n username = newName!! // the type of newName!! is String and the compiler generates a runtime check to be sure of that...\n }\n}\n```\n\nThe equivalent Java code as taken from the bytecode generated by the Kotlin compiler is as follows:\n\n```kotlin\nimport org.jetbrains.annotations.Nullable;\n\nimport static kotlin.jvm.internal.Intrinsics.throwNpe;\n\npublic final class User {\n private String username = \"\";\n\n public void setName(@Nullable newName: String) {\n if (newName == null) {\n throwNpe();\n }\n\n username = newName;\n }\n}\n```\n\nWe can see a couple of interesting things here:\n\n1. The `newName` parameter of the `setName` method gets an annotation indicating its _nullability_. This annotation is used internally by Kotlin compiler and [IntelliJ IDEA](https://www.jetbrains.com/idea/), although one can think of using it also in tools like [FindBugs](http://findbugs.sourceforge.net/) or [Checker Framework](http://types.cs.washington.edu/checker-framework/current/checker-framework-manual.html#nullness-checker).\n2. The code in `setName` has a striking resemblance (surprise!) to the code we wrote in our smart cast example. The only difference is the usage of the `throwNpe` method. Weʼll delve into the details in part 2 – for now we can make a simplification and state that it throws `KotlinNullPointerException` (which extends `NullPointerException`).\n\n### Parameter validation\n\nSo far in our examples we didnʼt have methods which were not private and at the same time had non-`null` parameters. In order to gain some insight into what happens in such situations letʼs modify our code:\n\n```kotlin\nclass User {\n var username: String = \"\"\n\n fun setName(newName: String) {\n username = newName\n }\n}\n```\n\nOne obvious method that weʼd like to have a look at is the `setName` method. But the equivalent Java code contains a surprise:\n\n```java\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport static kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull;\n\npublic class User {\n @NotNull\n private String username = \"\";\n\n @NotNull\n public String getUsername() {\n return username;\n }\n\n public void setUsername(@NotNull String value) {\n checkParameterIsNotNull(value, \"\");\n\n username = value;\n }\n\n public void setName(@NotNull String newName) {\n checkParameterIsNotNull(value, \"newName\");\n\n username = value;\n }\n}\n```\n\nWe can see that we now have two additional methods (`getUsername` and `setUsername`) and the `username` field earned a `@NotNull` annotation. Weʼre witnesses to how Kotlin compiler manages properties in classes:\n\n1. If it is `private` then a property is simply a field of the class with no special annotations – this is because this property is not visible anywhere outside the class and therefore Kotlin compiler can optimize access to it and it can be sure that the field will always be non-`null`.\n2. If it is not `private` then a property is actually a field with a pair of setter and getter methods – this is because the property is visible to the outside world and Kotlin compiler must check upon every access that it is non-`null` and at the same time provide this information to this outside world.\n\nWe can also observe that to check whether a value of a parameter is not `null` the `checkParameterIsNotNull` method is used. Again weʼll investigate this method in part 2. For now it is enough to say that upon receiving a `null` value an `IllegalArgumentException` will be thrown.\n\n### Elvis operator\n\nWhen we have a `null` value there are situations when instead of throwing an exception weʼd rather do something else. We can compare this to a `default` block in Java `switch` statement. A simple `if` statement with an `else` should suffice here, but Kotlin has a special syntax for it – the famous [Elvis operator](https://en.wikipedia.org/wiki/Elvis_operator).\n\nLetʼs suppose that for a `null` value weʼd like to set `username` to `\"N/A\"`:\n\n```kotlin\nclass User {\n private var username: String = \"\"\n\n fun setName(newName: String?) {\n username = newName ?: \"N/A\"\n }\n}\n```\n\nThe equivalent Java code is:\n\n\n```java\nimport org.jetbrains.annotations.Nullable;\n\npublic class User {\n private String username = \"\";\n\n public void setName(@Nullable String newName) {\n username = (newName != null) ? newName : \"N/A\";\n }\n}\n```\n\n\nThe Kotlin syntax is more concise and itʼs also worth mentioning that the expression after the Elvis operator is lazily evaluated and it can also throw an exception. So itʼs completely legal to have this kind of code:\n\n```kotlin\nclass User {\n private var username: String = \"\"\n\n fun setName(newName: String?) {\n username = newName ?: throw RuntimeException(\"Are you nuts?\")\n }\n}\n```\n\nThe equivalent Java code is:\n\n\n```java\nimport org.jetbrains.annotations.Nullable;\n\npublic class User {\n private String username = \"\";\n\n public void setName(@Nullable String newName) {\n if (newName != null)\n username = newName;\n else\n throw new RuntimeException(\"Are you nuts?\");\n }\n}\n```\n\n### Safe calls and let/run/apply functions\n\nThere are circumstances when we have a possibly `null` object and we want to invoke a method on it but only if it is actually non-`null` (because otherwise we would get `NullPointerException`). We can do it with simple `if`, but Kotlin provides a fancy `?.` operator to make the code more compact. So this code:\n\n```kotlin\ndata class SimpleUser(var name: String)\n\nobject Users {\n private val userMap = mapOf(1 to SimpleUser(\"John\"))\n\n @JvmStatic\n fun getUser(userId: Int): SimpleUser? = userMap[userId]\n}\n\nfun getUserName(userId: Int): String? =\n getUser (userId)?.name\n```\n\nhas the following equivalent Java code for `getUserName`:\n\n\n```java\n@Nullable\npublic String getUserName(int userId) {\n SimpleUser simpleUser = getUser(userId);\n return simpleUser != null ? simpleUser.getName() : null;\n}\n```\n\nKotlin code is indeed a lot shorter and more expressive. To further aid developers Kotlin provides three convenient [higher-order functions](https://kotlinlang.org/docs/reference/lambdas.html#higher-order-functions): `let`, `run` and `apply`. Although they are not directly related to `null`-safety issues we often use them with potentially `null` objects. Below you can find some code examples – they should give you an intuition about when and how to use them.\n\n#### let\n\nLetʼs look at the following code with [`let`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html) (pardon the pun):\n\n```kotlin\nfun findUserNameWithLet(userId: Int): String? =\n getUser (userId)?.let { it.name }\n```\n\n`let` is essentially an [extension function](https://kotlinlang.org/docs/reference/extensions.html#extension-functions) (i.e. a method of a class which you can define outside of the class definition) that can be invoked on any type. It takes a [lambda expression](https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions) as its parameter and calls the expression with `this` as an argument. If a _lambda expression_ has only one parameter then we may skip declaring it and simply access the parameter via the name... `it`. Therefore in the example above `this` inside the lambda (`this` is of type `SimpleUser` – the type returned by the `getUser` method) is accessible as `it`. The value of the _lambda expression_ is returned as the result of the `let` function.\n\nThe equivalent Java code for `findUserNameWithLet` is as follows:\n\n```java\n@Nullable\npublic String findUserNameWithLet(int userId) {\n String result;\n\n SimpleUser simpleUser = getUser(userId);\n if (simpleUser != null) {\n SimpleUser it = simpleUser;\n\n result = it.getName(); // { it.name }\n } else {\n result = null;\n }\n\n return result;\n}\n```\n\n`let` is usually used if we want to perform some operations on a non-`null` object and return the result of these operations while simply returning `null` for `null` objects.\n\n#### run\n\nThe [`run`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run.html) function is a slight variation of `let`. It takes a parameterless _lambda expression_ as its parameter and the object on which you invoke `run` can be accessed via `this` inside the _lambda expression_. Just like in `let` the result of the _lambda expression_ is returned as the result of the `run` function.\n\nLetʼs see an example:\n\n```kotlin\nfun findUserNameWithRun(userId: Int): String? =\n getUser (userId)?.run { name }\n```\n\nand the equivalent Java code:\n\n```kotlin\n@Nullable\npublic String findUserNameWithRun(int userId) {\n String result;\n\n SimpleUser simpleUser = getUser(userId);\n if (simpleUser != null) {\n SimpleUser $receiver = simpleUser;\n\n result = $receiver.getName(); // { name }\n } else {\n result = null;\n }\n\n return result;\n}\n```\n\nAs we can see there is little difference with `let` – Kotlin code is similar although with `run` it is even more concise.\n\n#### apply\n\nThe last of the three convenient functions weʼre going to talk about is [`apply`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html). The following code illustrates its usage:\n\n```kotlin\nfun findUserNameWithApply(userId: Int): SimpleUser? =\n getUser (userId)?.apply { name = \"Jane\" }\n}\n```\n\n`apply` is similar to `run` – it is an _extension function_ which takes a parameterless _lambda expression_ as its parameter and the object on which you invoke `apply` can be accessed via `this` inside the _lambda expression_. However, the return value of `apply` is the object on which you invoke it (and not the _lambda expression_ result).\n\nThe equivalent Java code for `findUserNameWithApply` is as follows:\n\n```java\n@Nullable\npublic SimpleUser findUserNameWithApply(int userId) {\n SimpleUser result;\n\n SimpleUser simpleUser = getUser(userId);\n if (simpleUser != null) {\n SimpleUser $receiver = simpleUser;\n\n $receiver.setName(\"Jane\"); // { name = \"Jane\" }\n\n result = simpleUser;\n } else {\n result = null;\n }\n\n return result;\n}\n```\n\nThe most common reason to use `apply` is the initialisation of an object. If there is something we have to do before returning an object (and simply return `null` if it is `null`) then `apply` is the way to go.\n\n### Platform types\n\nSo far we have not talked about the interoperability with Java. While from Java code point of view with regard to `null`-safety nothing unusual happens if we call Kotlin code, there is a difference when we want to call Java code from Kotlin. This is especially important for the case of the result returned from Java method where Kotlin compiler has to take some precautions. After all it does not know if the value returned can be `null` or not.\n\nTo resolve this problem Kotlin introduces the concept of [platform types](https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types). In essence _platform type_ is used every time Kotlin compiler encounters an invocation of Java method which was not generated by Kotlin compiler. At the same time a developer cannot explicitly declare anything to be of _platform type_ – it exists solely when Kotlin compiler infers it from the code.\n\nLetʼs look at some code samples which present most of things you have to know about _platform types_:\n\n```kotlin\nfun writeOutNullable(s: String?) = println(s)\n\nfun nullableCase() {\n val value = System.getProperty(\"key\") // value has a platform type String!\n writeOutNullable(value) // The ! after a type indicates it's a platform type\n}\n```\n\nThe equivalent Java code is:\n\n```java\npublic void nullableCase() {\n String value = System.getProperty(\"key\");\n writeOutNullable(value);\n}\n```\n\nWe can see nothing special here – the _platform type_ is taken as is when it is converted to a _nullable_ type.\n\nLetʼs see what happens when the target type is non-`null`:\n\n```kotlin\nfun writeOut(s: String) {\n println(s)\n}\n\nfun nonNullCase() {\n val value = System.getProperty(\"key\") // value has a platform type String!\n\n writeOut(value)\n}\n```\n\nThe equivalent Java code is:\n\n```java\nimport static kotlin.jvm.internal.Intrinsics.checkExpressionValueIsNotNull;\n\npublic void nonNullCase() {\n String value = System.getProperty(\"key\");\n\n checkExpressionValueIsNotNull(value, \"value\");\n writeOut(value);\n}\n```\n\nNow we have a validation in the generated code. `writeOut` expects a non-`null` type, but the `value` type is _platform type_ and in theory it could be `null`. Therefore the compiler produces a runtime check with the help of `checkExpressionValueIsNotNull` method which weʼll explore in part 2.\n\nNext example shows the code where only Java methods are used.\n\n```kotlin\nfun pureJavaCase() {\n val value = System.getProperty(\"key\") // value has a platform type String!\n\n System.setProperty(\"other_key\", value)\n}\n```\n\nThe equivalent Java code is:\n\n```java\npublic void pureJavaCase() {\n String value = System.getProperty(\"key\");\n\n System.setProperty(\"other_key\", value);\n}\n```\n\nJust like when we had the _nullable_ types no runtime check is generated. After all at no place in the code do we pass the value to the code which explicitly expects non-`null` values.\n\nOne might ask what happens after the value is checked not to be `null` – does the compiler treat it as a non-`null` value?\n\n```kotlin\nfun doubleCheckCase() {\n val value = System.getProperty(\"key\") // value has a platform type String!\n\n writeOut(value)\n writeOut(value)\n}\n```\n\nThe equivalent Java code is:\n\n```java\npublic void doubleCheckCase() {\n String value = System.getProperty(\"key\");\n\n checkExpressionValueIsNotNull(value, \"value\");\n writeOut(value);\n checkExpressionValueIsNotNull(value, \"value\");\n writeOut(value);\n}\n```\n\nIt appears it doesnʼt – the runtime checks are generated each time the conversion to non-`null` type takes place.\n\nThe following example shows assigning the value with _platform type_ to some variable without explicitly stating this variable type:\n\n```kotlin\nfun assignCase() {\n val value = System.getProperty(\"key\") // value has a platform type String!\n val newValue = value // newValue has a platform type String!\n\n writeOut(newValue)\n}\n```\n\nThe equivalent Java code is:\n\n```java\npublic void assignCase() {\n String value = System.getProperty(\"key\");\n String newValue = value;\n\n checkExpressionValueIsNotNull(newValue, \"newValue\");\n writeOut(newValue);\n}\n```\n\nNo surprise here – the type of the variable `newValue` is also a _platform type_ and runtime checks are generated.\n\nWhat if we explicitly state the variableʼs type?\n\n```kotlin\nfun explicitCase() {\n val value = System.getProperty(\"key\") // value has a platform type String!\n\n val nullableValue: String? = value\n writeOutNullable(nullableValue)\n\n val nonNullValue: String = value\n writeOut(nonNullValue)\n writeOut(nonNullValue)\n}\n```\n\nThe equivalent Java code is:\n\n```java\npublic void explicitCase() {\n String value = System.getProperty(\"key\");\n\n String nullableValue = value;\n writeOutNullable(nullableValue);\n\n checkExpressionValueIsNotNull(value)\n String nonNullValue = value;\n writeOut(nonNullValue);\n writeOut(nonNullValue);\n}\n```\n\nAs we can see the rule is simple – every time we go from the _plaform type_ to non-`null` type a runtime check is generated. Once weʼre in the `null`-safe world no additional validation is needed.\n\nIn the examples above weʼve seen that the `checkExpressionValueIsNotNull` method takes a variable name as the second parameter. This is done so that when a `null` value is passed youʼll see an error message with the name of the variable in it. But as the name of the method implies the second parameter does not have to be a variable name. In fact itʼs always an expression name, but in the cases presented above we had simple one-variable expressions. If we had a more complicated expression...:\n\n```kotlin\nfun funnyCase() {\n writeOut(System.getProperty(\"key\"))\n}\n```\n\nThe equivalent Java code is:\n\n```java\npublic void funnyCase() {\n String tmp = System.getProperty(\"key\");\n checkExpressionValueIsNotNull(tmp, \"System.getProperty(\\\"key\\\")\");\n writeOut(tmp);\n}\n```\n\nIf we now call `funnyCase` (and there is no `\"key\"` system property set) then weʼll see the following stack trace:\n\n```\nException in thread \"main\" java.lang.IllegalStateException: System.getProperty(\"key\") must not be null\n at pl.kk.test.kotlin.PlatformTypesKt.funnyCase(PlatformTypes.kt:54)\n at pl.kk.test.kotlin.FunnyCaseCall.main(PlatformTypes.kt:60)\n```\n\n### Summary\n\nWeʼve taken a tour of different Kotlin language constructs where you could observe the code generated by the compiler. During regular development you rarely have to think about how things work under the hood. Nonetheless it is useful to know a thing or two about it. And if youʼre interested in the performance issues surrounding some of those constructs check out the second part of this article which will be soon published.\n\n","author":"Konrad Kamiński","date":"2016-06-20","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Developing Spring Boot applications with Kotlin.","url":"https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin","body":"\nJust in time for [Kotlin 1.0 release](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/), we are adding support for Kotlin language to [https://start.spring.io](https://start.spring.io/#!language=kotlin) in order to make it easier to start new Spring Boot projects with this language.\n\nThis blog post is also an opportunity for me to explain why I find this language interesting, to show you a sample project in detail and to give you some tips.\n\n## What is Kotlin?\n\n[Kotlin](https://kotlinlang.org/) is a language created by [JetBrains](https://www.jetbrains.com/). It runs on top of the JVM (but not only), it is an object oriented language that includes many ideas from functional programming. I won’t go too much in details about all Kotlin features ([PDF](https://kotlinlang.org/docs/kotlin-docs.pdf), [HTML](https://kotlinlang.org/docs/reference/)), but I would like to highlight the ones I find the most interesting:\n\n* Kotlin is a statically typed language, but thanks to its [clever type inference](https://kotlinlang.org/docs/reference/basic-types.html), it allows you to write code as short and expressive as dynamic language with performances close to pure Java projects\n* [Properties support](https://kotlinlang.org/docs/reference/properties.html#declaring-properties)\n* Relatively lightweight standard library compared to other languages\n* Easy to learn: a Java developer can quickly understand most of the language (this [quick comparison to Java](https://kotlinlang.org/docs/reference/comparison-to-java.html) is worth to read)\n* [Java interop](https://kotlinlang.org/docs/reference/java-interop.html) is a first class concern and great\n* Perfect for Android development\n* Built-in immutability and [null safety](https://kotlinlang.org/docs/reference/null-safety.html) support\n* Code is easy to read, efficient to write\n* Allows to [extend existing libraries](https://kotlinlang.org/docs/reference/extensions.html) without having to inherit from the class or use any type of design pattern such as Decorator\n* No semicolon required ;-)\n\nYou will find a lot of useful links to improve your Kotlin knowledge in this [Kotlin digest 2015](http://blog.jetbrains.com/kotlin/2016/01/kotlin-digest-2015/) blog post. Also have a look to these simple [Kotlin exercices](http://try.kotlinlang.org/koans) to have a quick overview of the language.\n\n## A sample Spring Boot + Kotlin project\n\nKotlin has been designed to play well with the Java ecosystem, and it seems to me that it shares the same pragmatic, innovative and opinionated mindset as Spring Boot, so they play well together. You can have a look at this simple [Spring Boot + Spring Data JPA Kotlin project](https://github.com/sdeleuze/spring-boot-kotlin-demo) to see more concretely what it looks like.\n\nKotlin allows to write (and read) your domain model easily thanks to [data classes](https://kotlinlang.org/docs/reference/data-classes.html). The compiler automatically derives the following members from all properties declared in the primary constructor:\n- `equals()` / `hashCode()` pair\n- `toString()` of the form “Customer(firstName=Foo, lastName=Bar, id=42)”\n- `componentN()` functions corresponding to the properties in their order or declaration\n- `copy()` function\n\nYou can see that Kotlin allows you to specify parameter default values, and types are declared after the name of the variable/parameter:\n\n```kotlin\n@Entity\ndata class Customer(\n\tvar firstName: String = \"\",\n\tvar lastName: String = \"\",\n\t@Id @GeneratedValue(strategy = GenerationType.AUTO)\n\tvar id: Long = 0\n)\n```\n\nThe Spring MVC REST controller you can see below is using constructor level injection, and default visibility in Kotlin is `public` so no need to specify it. When a function returns a single expression, the curly braces can be omitted and the body is specified after a `=` symbol. It is even better since the return type can be inferred by the compiler.\n\n```kotlin\n@RestController\nclass CustomerController @Autowired constructor(val repository:CustomerRepository) {\n\n\t@RequestMapping(\"/\")\n\tfun findAll() = repository.findAll()\n\n\n\t@RequestMapping(\"/{name}\")\n\tfun findByLastName(@PathVariable name:String)\n\t\t= repository.findByLastName(name)\n}\n```\n\nThe Spring Data repository is self explanatory:\n\n```kotlin\ninterface CustomerRepository : CrudRepository {\n\tfun findByLastName(name: String): List\n}\n```\n\nSince Kotlin supports top-level functions, you can declare your application as simple as:\n\n```kotlin\n@SpringBootApplication\nopen class Application {\n\n\t@Bean\n\topen fun init(repository: CustomerRepository) = CommandLineRunner {\n\t\trepository.save(Customer(\"Jack\", \"Bauer\"))\n\t\trepository.save(Customer(\"Chloe\", \"O'Brian\"))\n\t\trepository.save(Customer(\"Kim\", \"Bauer\"))\n\t\trepository.save(Customer(\"David\", \"Palmer\"))\n\t\trepository.save(Customer(\"Michelle\", \"Dessler\"))\n\t}\n}\n\nfun main(args: Array) {\n\tSpringApplication.run(Application::class.java, *args)\n}\n```\n\nYou need to mark `@Configuration` classes, some others like most `@Component` ones and `@Bean` methods as `open` because they cannot be `final` in Spring due to proxy usage (classes and methods in Kotlin are `final` by default without the `open` modifier).\n\n## Additional tips\n\nEven if Spring Boot and Kotlin work pretty well together, these additional tips are worth to know.\n\n\n### Property injection\n\nWe have seen previously how to do constructor injection, since that’s the [recommended approach](http://olivergierke.de/2013/11/why-field-injection-is-evil/) (especially with Kotlin). If you have to perform property injection, you will have to use [late-initialized properties](https://kotlinlang.org/docs/reference/properties.html#late-initialized-properties) because normally, raw properties declared as having a non-null type must be initialized in the constructor.\n\n```kotlin\n@RestController\nclass CustomerController {\n\n\t@Autowired\n\tlateinit var repository:CustomerRepository\n\n\t// ...\n}\n```\n\n### Property placeholders\n\n`$` is used for [String interpolation](https://kotlinlang.org/docs/reference/basic-types.html#string-templates) in Kotlin, so you should escape it when using property placeholders: `@Value(\"\\${some.property}\")`. As an alternative you can also use `@ConfigurationProperties` instead, see [this Stack Overflow](http://stackoverflow.com/a/33883230/1092077) answer for more details.\n\n### Array annotation attribute\n\nUnlike Java, Kotlin does not allow to specify array annotation attribute as a single value, so be aware that you will have to write `@RequestMapping(method = arrayOf(RequestMethod.GET))` or `@EnableAutoConfiguration(exclude = arrayOf(Foo::class))`.\n\nIt will be possible to use a shorter syntax with upcoming Spring Framework 4.3 composed annotations like `@GetMapping`, see [SPR-13992](https://jira.spring.io/browse/SPR-13992) for more details.\n\n### Jackson Kotlin Module\n\nIf you are using Jackson you are likely to want to add `com.fasterxml.jackson.module:jackson-module-kotlin` dependency in order to allow it to deal with data classes with no default constructor or with Kotlin collections.\n\nIn addition to the dependency, you need to register it in Jackson `ObjectMapper`:\n\n```kotlin\n@SpringBootApplication\nopen class Application {\n\n\t@Bean\n\topen fun objectMapperBuilder(): Jackson2ObjectMapperBuilder\n\t = Jackson2ObjectMapperBuilder().modulesToInstall(KotlinModule())\n\n\t// ...\n}\n```\n\n### Experiment with the Java to Kotlin converter\n\nLast tip, the Java to Kotlin converter available in IntelliJ IDEA (Menu Code -> Convert Java file to Kotlin file) is quite useful when you can’t figure out how to write something in Kotlin. So do not hesitate to write something in Java and use it to find the Kotlin counterpart. This [comparison to Java documentation](https://kotlinlang.org/docs/reference/comparison-to-java.html) can also provide some help.\n\n## Feedbacks\n\nWe are interested by your feedbacks about developing Spring applications with Kotlin. This blog post is just an introduction, there is much more to say especially about using Spring Boot with more Kotlin idiomatic code like with [Exposed](https://github.com/JetBrains/Exposed) SQL library, so stay tuned ...\n\n","author":"Sébastien Deleuze","date":"2016-02-15","type":"article","categories":["Kotlin","Spring"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"When Kotlin met Gradle","url":"https://jaxenter.com/when-kotlin-met-gradle-126726.html","body":"\n_Love story alert_\n\n![Kotlin](https://jaxenter.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-06-at-2.56.13-PM.png)\n\nSource: [http://gradle.org/](http://gradle.org/)\n\nThe idea of having a Kotlin-based approach to writing Gradle build scripts and plugins was enticing enough to convince the JetBrains team and the Gradle team to concoct a way to get the best of both worlds. And this is how Gradle Script Kotlin was born.\n\nKotlin seems tireless these days! First, Gradle announced what they call _[Gradle Script Kotlin](http://gradle.org/blog/kotlin-meets-gradle/)_; then JetBrains announced [a new release of their plugin](https://blog.jetbrains.com/kotlin/2016/06/kotlin-eclipse-plugin-0-7-is-here/) for Eclipse IDE. But first things first!\n\n## Gradle + Kotlin = New project\n\nGradle’s Chris Beams [announced](http://gradle.org/blog/kotlin-meets-gradle/) in mid-May that after years of closely watching Kotlin, the team sat down with some people from the JetBrains team in late 2015 and tried to answer the following questions: what might it look like to have a Kotlin-based approach to writing Gradle build scripts and plugins? How might it help teams—especially big ones—work faster and write better structured, more maintainable builds?\n\nKotlin could give Gradle users proper IDE support from auto-completion to refactoring and everything in-between since this statically-typed language offers deep support in both IDEA and Eclipse. Plus, the fact that it is rich with features such as first-class functions and extension methods means that it could retain and improve on the best parts of writing Gradle build scripts. The result is called Gradle Script Kotlin, a Kotlin-based build language for Gradle.\n\n[The first milestone](https://github.com/gradle/gradle-script-kotlin/releases/tag/v1.0.0-M1) towards version 1.0 was launched less than a month ago and its repository was open-sourced at [https://github.com/gradle/gradle-script-kotlin](https://github.com/gradle/gradle-script-kotlin). Take a look at the outcome:\n\n[![Screen Shot 2016-06-06 at 3.28.27 PM](https://jaxenter.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-06-at-3.28.27-PM.png)](http://gradle.org/blog/kotlin-meets-gradle/)\n\nSource: [http://gradle.org/blog/kotlin-meets-gradle/](http://gradle.org/blog/kotlin-meets-gradle/)\n\n\nAs you begin to explore what’s possible in the IDE, you will will be able to ‘play with’ things such as refactoring, quick documentation, auto-completion and content assist, navigation to source and more.\n\n## Kotlin Eclipse plugin 0.7\n\nRoughly two weeks after _Gradle Script Kotlin_ was announced, Kotlin returned to the spotlight thanks to a new release. In addition to the support for Kotlin 1.0.2 compiler, Eclipse plugin 0.7 brings highly important features and improvements such as a rebuilt code formatting feature and the _Organize Imports_ feature which cleans unused imports, adds missing imports for classes used in the file and resorts them.\n\nThe team also added some quick-fixes about missing or illegal modifiers. As a result, it is now possible to add an open modifier to a declaration which is overridden or subclassed and it is easy to deal with the “class must be declared abstract” compiler error. Plus, invalid modifier removing is now available for the quick-fix popup.\n\n","author":"Gabriela Motroc","date":"2016-06-06","type":"article","categories":["Kotlin","Gradle"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin EE: Boost your Productivity","url":"https://www.youtube.com/watch?v=fpjDY6XRBJM","body":"\n# v1\n\nKotlin is a language for the JVM, invented by JetBrains a few years ago. But what the hell is Kotlin EE? If you never heard of Kotlin EE, don’t panic, it does not exist. But you can use it right away and boost your productivity!\n\nI invented the term Kotlin EE as a synonym for using the Kotlin language together with the Java EE API to create services of any size (microservices, nanoservices etc.) with just a few lines of code and the ability to focus on the business logic.\n\nKotlin and Java EE are a perfect couple for writing micro- or nanoservices. Kotlin is a very pragmatic language, builds on many concepts and techniques from Java, designed for developer productivity. Kotlin works great with all existing Java libraries and frameworks and runs with the same level of performance as Java.\n\nThe Java EE API allows us to code against a proven and stable API. Provided libraries like JAX-RS for writing RESTful APIs and Jackson for JSON (de)serializing decrease the need for additional third-party libraries which results in a short build time and a small artifact size. Benefit from a very fast build and test feedback and stay focused on your code.\n\nIn this talk, I try to prove my statements from above. Live on stage I write a service in Kotlin with a RESTful JSON API with only a few lines of code and run the service using a local Docker cloud where you can see how these can be scaled up and down to manage fluctuating loads. Coding, building, testing, deploying, scaling: fast and efficient!\n\n\n\n","author":"Marcus Fihlon @ Voxxed Days Bucharest","date":"2018-03-23","type":"video","categories":["Cloud","Docker","Jakarta EE","Java EE","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The Journey of a Spring Boot application from Java 8 to Kotlin, part 2: Configuration Classes","url":"http://engineering.pivotal.io/post/spring-boot-configuration-in-kotlin/","body":"\nIn the [first post](/post/spring-boot-application-with-kotlin/) of this series, we looked at the conversion of a Spring Boot application class from Java 8 to Kotlin. The nice thing about these migrations is that they can be done incrementally since Kotlin plays very nicely with legacy Java. In fact, it was one of the design considerations for the language.\n\nIn this second post, we will look at the conversion of a configuration class into Kotlin.\n\nHere is an example of a Spring Boot configuration class as written in Java 8:\n\n```kotlin\npackage com.example.billing;\n\nimport com.example.billing.reocurringPayments.Service;\nimport com.example.payments.RecurlyGateway;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\nclass Configuration {\n @Bean\n public com.example.payments.Gateway paymentGateway() {\n return new RecurlyGateway();\n }\n\n @Bean\n public Service serviceThatMayFail() {\n return new Service();\n }\n}\n```\n\nHere is that same configuration class written in Kotlin:\n\n```kotlin\npackage com.example.billing\n\nimport com.example.billing.reocurringPayments.Service\nimport com.example.payments.RecurlyGateway\nimport org.springframework.context.annotation.Bean\nimport org.springframework.context.annotation.Configuration\n\n@Configuration\nopen class Configuration {\n @Bean\n open fun paymentGateway() = RecurlyGateway()\n\n @Bean\n open fun serviceThatMayFail() = Service()\n}\n```\n\nThere aren't a bunch of huge differences but here are some of the smaller differences that stand out to me:\n\n* The Configuration class must be declared open. This is because Spring Boot subclasses your configuration class but Kotlin makes them final by default. See [here](https://kotlinlang.org/docs/reference/classes.html#inheritance) for details.\n* The @Bean functions must be declared open for the same reason as above.\n* There are no return types on the functions because Kotlin will infer the types. This type inference is one of\nmy favorite features of Kotlin.\n* Kotlin has implicit returns (and no braces) for [single-expression functions](https://kotlinlang.org/docs/reference/functions.html#single-expression-functions). When you only have one expression in a function body, Kotlin will automatically assume that you want to return that value so there is no need for an explicit `return` or braces. For bodies with multiple expressions, the `return` is still mandatory because the compiler may not be able to guess what the return type is for the function.\n* No `new` keyword when initializing an object. This coupled with the type inference, implicit returns and single statement/no braces makes for a nice compact configuration class.\n\nSpring configuration classes are a mixed bag for me in Kotlin. The actual code difference is only 4 lines of code (18 vs 14) but the visual noise is significantly reduced in Kotlin. Having to declare both the class and all of the methods as open seems a bit clunky for me but I'm willing to overlook it due to the type inference, lack of return for single expression functions and the other improvements that these classes gain from Kotlin.\n\nThanks for reading. In our next installment, we will take a look at Spring controllers in Kotlin.\n\n","author":"Mike Gehard","date":"2016-02-23","type":"article","categories":["Spring Boot","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The Kobalt diaries: Automatic Android SDK management","url":"http://beust.com/weblog/2016/04/09/the-kobalt-diaries-automatic-android-sdk-management/","body":"\n![](http://beust.com/pics/sdk-manager.png)\n**The dreaded SDK Manager**\n\nAndroid has always had a weird dependency mechanism. On the JVM (and therefore, Android), we have this great Maven repository system which is leveraged by several tools (Gradle and Kobalt on Android) and which allows us to add dependencies with simple additions to our build files. This is extremely powerful and it has undoubtedly been instrumental in increasing the JVM’s popularity. This system works for pretty much any type of applications and dependencies.\n\nExcept for Android libraries.\n\nThe Android support libraries (and I’m using “support” loosely here to include all such libraries and not just the one that Google calls “support”) are not available on any of the Maven repositories. They are not even available on Google’s own repository. Instead, you need to use a special tool to download them, and once you do that, they land on your local drive as a local Maven repository, which you then need to declare to Gradle so you can finally add the dependencies you need.\n\nI suspect the reason why these libraries are not available in a straight Maven repo is that you need to accept licenses before you can use them, but regardless, this separate download management makes building Android applications more painful, especially for build servers (Travis, Jenkins) which need to be configured specifically for these builds.\n\nThe graphical tool used to download this repository, called “SDK Manager”, is also a command tool called `\"android\"` that can be invoked without the GUI, and inspired by [Jake Wharton’s sdk-manager-plugin](https://github.com/JakeWharton/sdk-manager-plugin), I set out to implement automatic SDK management for [Kobalt](http://beust.com/kobalt).\n\nOnce I became more comfortable with the esoteric command line syntax used by the `\"android\"` tool, adding it to the Kobalt Android plug-in was trivial, and as a result, Kobalt is now able to completely install a full Android SDK from scratch.\n\nIn other words, all you need in your project is a simple Android configuration in your `Build.kt` file:\n\n```kotlin\nandroid {\n compileSdkVersion = \"23\"\n buildToolsVersion = \"23.0.1\"\n // ...\n}\n\ndependencies {\n compile(\"com.android.support:appcompat-v7:aar:23.0.1\")\n}\n```\n\nThe Kobalt Android plug-in will then automatically download everything you need to create an `apk` from this simple build file:\n\n* If `$ANDROID_HOME` is specified, use it and make sure a valid SDK is there. If that environment variable is not specified, install the SDK in a default location (`~/.android-sdk`).\n* If no Build Tools are installed, install them.\n* Then go through all the Google and Android dependencies for that project and install them as needed.\n* And a few other things...\n\nA typical run on a clean machine with nothing installed will look like this:\n\n```bash\n$ ./kobaltw assemble\n...\nAndroid SDK not found at /home/travis/.android/android-sdk-linux, downloading it\nCouldn't find /home/travis/.android/android-sdk-linux/build-tools/23.0.1, downloading it\nCouldn't find /home/travis/.android/android-sdk-linux/platform-tools, downloading it\nCouldn't find /home/travis/.android/android-sdk-linux/platforms/android-23, downloading it\nCouldn't find Maven repository for extra-android-m2repository, downloading it\nCouldn't find Maven repository for extra-google-m2repository, downloading it\n...\n ===========================\n | Building androidFlavors |\n ===========================\n------ androidFlavors:clean\n------ androidFlavors:generateR\n------ androidFlavors:compile\n Java compiling 4 files\n------ androidFlavors:proguard\n------ androidFlavors:generateDex\n------ androidFlavors:signApk\nCreated androidFlavors/kobaltBuild/outputs/apk/androidFlavors.apk\n```\n\nObviously, these downloads will not happen again unless you modify the dependencies in your build file.\n\nI’m hopeful that Google will eventually make these support libraries available on a real remote Maven repository so we don’t have to jump through these hoops any more, but until then, Kobalt has you covered.\n\nThis feature is available in the latest [`kobalt-android` plug-in](https://github.com/cbeust/kobalt-android) as follows:\n\n```kotlin\nval p = plugins(\"com.beust:kobalt-android:0.81\")\n```\n\n","author":"Cédric Beust","date":"2016-04-09","type":"article","categories":["Kotlin","Kobalt"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"My Kotlin Adventure","url":"http://cirorizzo.net/2016/01/23/kotlin-at-glance/","body":"\n###### _Part 1_\n\nMy first thought when I heard about Kotlin for the first time was \"_Just another language to write the same thing using new keywords!_\"\n\nLuckily, I’m hugely curious and this thought wasn’t enough to stop me looking into it further. I started reading about it and the more I read, the more I became intrigued...\n\nNow let me say:\n\n> Kotlin is not just another language, it uses another **paradigm** to help developers to solve everyday challenges\n\n#### Android Developers\n\nI’ve been working with Android since 2010, initially just because I was curious to explore the potential of the promising platform from the big *G, but later for several commissioned projects. For each project, I used the standard language that was available: **Java** (just in some spare cases using C with NDK). From it’s release, the Android SDK promised to give a boost to Java using a custom library for Mobile developing and so far it’s been good.\n\nSince the beginning The Android SDK really has been oriented to solve the Mobile challenges (UI responsiveness, Network availability, Sensors API), release after release, improving every time. The first JVM Dalvik did a very good job and the ART even more... \nBut I was still getting still stuck with Java (_enhanced 1.6_) and all its Ceremonies in the code.\n\n#### Android Studio\n\nMy first projects were on Eclipse IDE and to be honest I found it very useful and reliable with a plenty of documentation and a vivid community, but Google had other plans. They called it **Android Studio**. \nThe first version of it was really unreliable, plenty of bugs and not easy to use, so I decided to wait a few versions before using it for my projects. \nFortunately it didn't take so much time to release a very good, stable and absolutely reliable version of a proper **Android Studio** with all the quality of **JetBrains** products. \nBut still Java was the language...\n\n#### New kids in town\n\nMeanwhile the Developer community starting to use new paradigms offered by different kinds of programming languages like the brand new _Swift2_ by **Apple** (and soon Open Source and available for **Linux** too), _Scala_, _Haskell/Miranda_, _F#_, etc. The functional programming paradigm rocked the Developers community like a tsunami, waking them up from the deep sleep of spending too many years working with imperative and procedural languages.\n\nBut the Android community still were stuck on Java, and even if the new Java 8 promised to refresh the language, the Android framework couldn't move on it due to the backward compatibility with the oldest version of libraries used by the framework. \nIn the meantime **JetBrains** was working on it’s own language, **Kotlin**.\n\n![Kotlin Logo](http://cirorizzo.net/content/images/2016/02/xKotlin-logo.png.pagespeed.ic.3prhfChkMF.png)\n\n\n#### Kotlin\n\nSince from the early Beta versions, Kotlin has astonished the Android Community (and even more like Back End and Front End developers, etc). It is definitely a _Concise_, _Neat_ language with 100% Java interoperability, studied by people who deeply know the issues and routines of development issues and how to afford them as best as they can. \nIn other words I started to experiment with it several months ago and have since decided to use it in my existing and further projects.\n\n#### Having a look to some code\n\nThis is just an example of how concise coding with Kotlin can be:\n\n```kotlin\nfun thisIsTheMethod(message: String) {\n buttonMessage.setOnClickListener {\n Toast.makeText(context, \"Here the message: $message\",\n Toast.LENGTH_LONG).show()\n }\n}\n```\n\n\nThe above method is a clear example of how easy it can be to simplify typical Android code using Java. It usually looks like:\n\n```java\npublic void thisIsTheMethod(final String message) {\n buttonMessage.setOnClickListener(new OnClickListener() {\n @Override\n public void onClick(View v) {\n Toast.makeText(getBaseContext(),\n String.format(\"Here the message: %s\", message),\n Toast.LENGTH_LONG).show();\n }\n });\n}\n```\n\n\nMost of the boilerplate code used to write in Android can be reduced with Kotlin, still having a clean and understandable code.\n\nAt a glance, the method or function _thisIsTheMethod_ in Kotlin is implicitly _public_ a if hasn't any return (_void_ in Java, in Kotlin will see next what is) doesn't need any further keywords\n\n```kotlin\nfun thisIsTheMethod(message: String) {...}\n```\n\nAlso the signature has param declaration quite different from Java. The type follow the param name but it hides something more: **Null Safety** type system.\n\nI like to report from the official documentation the following:\n\n> Kotlin’s type system is aimed to eliminate NullPointerException’s from our code\n\nJust this should be something Android developers will love.\n\nAnd last but not least the _setOnClickListener_ for the view (_buttonMessage_) that can be reduced in a SAM (Single Abstract Method) through the Lambda Expression. Yes, finally!\n\n```kotlin\nbuttonMessage.setOnClickListener() {...}\n```\n\nWell, that’s it for now. I'm gonna go further in future posts to share more about the language and the benefits Kotlin has brought to my Android coding\n\nIt really is easy to switch to Kotlin from Java. Maybe now is the time for you to give it a closer look? \n[Jump to part two](http://www.cirorizzo.net/2016/02/03/kotlin-code/)\n\n","author":"Ciro Rizzo","date":"2016-01-23","type":"article","categories":["Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin + Android First Impressions","url":"https://www.javacodegeeks.com/2016/04/kotlin-android-first-impressions.html","body":"\nI am a huge Android fanboy, and have been one ever since the Nexus One came out. The Android OS has evolved so much and into so many variations. Almost a year ago, one of the Android developers I follow on Twitter was pushing for Kotlin to be the main language for Android. What was more interesting was it was retweeted by an Android Developer from Google. Fast forward to around this time, and the guys behinds IntelliJ announce 1.0 of Kotlin.\n\nI decided to see what the big hype was about on Kotlin. Consider this blog as a first impression rather than a review.\n\n## Going from Java to Kotlin\n\n[Kotlin](https://github.com/Kotlin) (for the most part) is similar to Groovy and Scala, as it runs on a JVM. It can also be compiled to JavaScript.\n\nI took the time to learn the syntax by first going to its official website. It’s advertised that Kotlin should be easy to pick up if you already code in Java, and it is interoperable with existing Java frameworks. I’ve been a Java developer most of my life, so I figured it wouldn’t be too hard to learn Kotlin.\n\nThe [official website](https://kotlinlang.org/) had a nice tutorial section for it. Here are a couple of cool things about the syntax I liked:\n\n* Types are defined after the variable name.\n In Java, you would declare variables with the type first then the variable name like `private int x;` while the Kotlin equivalent is `var x: Int`.\n The type can also be inferred `var x = 1 //is Int initialized to 1`.\n* Variables can be declared as nullable with `?`.\n For example: `y?.length`. If y is null, then return null. Otherwise return `y.length`.\n* Smart Casts! If a variable is of certain type, it is already cast to that type.\n For example: `if (a is String) print(a.length)`\n\nThere are a lot more that I liked, but to keep this blog short, I suggest you check out [the official website](https://kotlinlang.org/).\n\n## Kotlin in Android Studio\n\nIt has been a while since I played around with the Android API. The last time I messed around with an Android app was around the time Android was known as “Jelly Bean.”\n\nSo, that said, I had to familiarize myself with the newer APIs such as [RecyclerView](http://developer.android.com/reference/android/support/v7/widget/RecyclerView.html) and new UI elements from the Design Support Library. Luckily, since Android Studio is from the same guys who did Kotlin, it was easy to integrate Kotlin into the SDK.\n\nFirst, I created a new project in Android Studio which created a default main activity. Then with the Android Studio Kotlin plugin, I am able to invoke an action to convert from Java to Kotlin. This will convert the Java code thats autogenerated in MainActivity.java to Kotlin in MainActivity.kt. It will also add the Kotlin dependency to your build.gradle.\n\n## Put away that Butterknife\n\nA nice Kotlin feature worth mentioning is that within an Activity or Fragment, you don’t have to call on findViewById to get a View widget. Simply refer to it by id.\n\nSo, instead of `TextView myTextView = (TextView) findViewById(R.id.myTextView)`, you can simply refer to the TextView widget by `myTextView`. Kotlin will get the reference to that view.\n\n## So, overall?\n\nRather than making, say, a Hello World app or an app with a generic List view, I decided to try out creating an app that plays sounds using MediaPlayer API to challenge myself.\n\n![Kotlin](https://www.javacodegeeks.com/wp-content/uploads/2016/04/Kotlin.png)\n\nDuring my experience with it as I coded the activities, inflating layouts, and RecyclerView adapters, I think I spent more time going back to the Android API documentation than I did with Kotlin. At first I had to refer back to the Kotlin docs to look up stuff until I got use to the syntax.\n\nWhat I liked most about Kotlin was there were less lines of code. When comparing things I would do in Java that would take a couple of lines, I could accomplish the same in Kotlin with just one line. Less lines of code is pleasant to my tiring eyes. Plus, less boilerplate which is helpful, especially in Android.\n\n## Anko\n\nYou could also use [Anko](https://github.com/Kotlin/anko) which is a UI library written in Kotlin. Instead of XML, Anko does the UI in DSL. I heard much praise for this tool. But as I started playing around with Kotlin, I wanted to be more familiar with Android’s default XML layout UI.\n\nMaybe one day I’ll write another blog on Anko or something :).\n\n## The future...\n\nSo what are the chances that Kotlin will indeed be the official, main go-to when coding in Android?\n\nThere have been rumors that Google is seeking to stray away from Java for Android development, there have been reports that [Google is looking into adopting Apple’s Swift language](http://thenextweb.com/dd/2016/04/07/google-facebook-uber-swift/). However, that same report also stated that Google isn’t considering Kotlin because of its long build times.\n\nWith all that said, if you’re an existing Java developer looking into something new or looking into developing Android apps, I would suggest to look into Kotlin and give it a try.\n\n","author":"Keyhole Software","date":"2016-04-20","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin без магии","url":"http://javanese.online/%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8/Kotlin_%D0%B1%D0%B5%D0%B7_%D0%BC%D0%B0%D0%B3%D0%B8%D0%B8/","body":"\nОбычно, когда открываешь для себя новый язык программирования, некоторые его конструкции выглядят, как магия. Например, for-each loop в Java:\n\n```kotlin\nfor (String s : strings) {\n /* ... */\n}\n```\n\nКакого типа должна быть ```strings```? Во что разворачивается эта конструкция?\n\n(для массива (допустим, ```T[]```) получается подобие ```for (int i = 0; i < array.length; i++) { T t = array[i]; /* ... */ }```, а для ```Iterable``` — нечто вроде ```for (Iterator itr = iterable.iterator; itr.hasNext(); ) { T t = itr.next(); /* ... */ }```)\n\nИли, скажем, как работает try-with-resources ( ```try (InputStream is = new FileInputStream(file)) { /* ... */ }```)? Какой ```finally``` вызовется раньше — сгенерированный компилятором и закрывающий ресурсы или наш собственный? Что нужно сделать чтобы собственный класс работал с try-with-resources? (ну да, реализовать ```AutoCloseable```)\n\nПример ещё проще и повседневнее.\n\n```java\nString first = getStringSomewhere();\nString second = \"first: \" + first;\nString third = \"first: \" + first + \"; hashCode: \" + first.hashCode();\n```\n\nКак переопределён оператор сложения? Где будет создаваться ```StringBuilder```, а где — нет?\n\nЕщё пример. Код на Groovy.\n\n```groovy\ndef personDetails = [firstName:'John', lastName:'Doe', age:25]\n```\n\nКакой класс у personDetails? ```HashMap```, ```TreeMap```, ```LinkedHashMap```, ```Collections$UnmodifiableMap```?\n\n## Что там про Kotlin?\n\nВ Kotlin нет магических и тайных языковых конструкций.\n\n```Array.forEach и Collection.forEach``` — это extension functions, которые определены как ```for (element in this) action(element)```. При Ctrl-клике (Cmd-клике) на ```in``` можно увидеть, что этот оператор работает с функциями ```iterator```, ```next``` и ```hasNext```. Последние, в свою очередь, определены как ```operator fun```, что и позволяет использовать их с языковыми конструкциями. То есть автор класса, написав ```operator fun```, явно разрешает использовать эту функцию как конструкцию языка.\n\nВ выражении ```someFile.bufferedReader.use { /* тот же try-with-resources */ }```, например, ```use``` — инлайновая (встраиваемая) extension-функция для ```Closeable```. Можно посмотреть в её код и понять, когда там вызывается ```finally```.\n\nВ коде ```val s = \"a\" + \"b\"``` можно Ctrl-кликнуть плюс и увидеть ```operator fun plus``` в классе ```kotlin.String```.\n\nВ конструкции ```val personDetails = mapOf(\"firstName\" to \"John\", \"lastName\" to \"Doe\", \"age\" to 25)``` можно заглянуть в реализацию ```mapOf``` (также есть ```mutableMapOf```, ```hashMapOf```, ```linkedMapOf```) и в реализацию ```to``` (```infix fun A.to(that: B): Pair = Pair(this, that)```).\n\nЛично для меня при всём синтаксическом разнообразии и гибкости Kotlin код на нём остаётся очень понятным. Можно создавать свои функции, которые благодаря модификаторам ```operator```, ```inline``` и ```infix``` выглядят как языковые конструкции, но всегда можно посмотреть в их реализацию, и нигде не будет чего-то вроде ```*тут магия компилятора*```.\n\n","author":"Mike Gorunov","date":"2016-12-28","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"Exercises in Kotlin: Part 3 - Functions","url":"http://blog.dhananjaynene.com/2016/04/exercises-in-kotlin-part-3-functions/","body":"\nWe looked at a bit of syntax and variable declarations in the last post [Exercises in Kotlin: Part 2 - High level syntax and Variables](http://blog.dhananjaynene.com/2016/04/exercises-in-kotlin-part-2-high-level-syntax-and-variables/). We explore functions in this post. Here's how a typical function in Kotlin would look like.\n\n```kotlin\nfun add(first: Int, second: Int): Int {\n // will not compile\n // first = first + 2. Because first is a val and cannot be reassigned\n return first + second\n}\n```\n\nAs noted earlier, the arguments are declared with the names followed by the types. Also even though `val` is not specified, each argument is automatically a `val` and can not be reassigned within the function. Also the return type is specified after the argument list followed by a colon.\n\nIn this case, since the body of the function is an expression it can also alternatively be specified as\n\n```kotlin\nfun addExpr(first: Int, second: Int) = first + second\n```\n\nNote in particular that the curly brackets are replaced by `=`. And because the compiler can infer the return type, it is no longer required to provide it (though it would work just as well if you did provide one)\n\n### Functions can have default arguments\n\n```kotlin\nfun powerOf(value: Double, power: Double = 2.0) = Math.pow(value, power)\n```\n\nThe second argument `power` is no longer required to be specified, (when not specified its value will default to 2.0. Thus allowing both the following statements\n\n```kotlin\npowerOf(3.0) // This will return 9.0\npowerOf(3.0, 4.0) // This will return 81.0\n```\n\nThis makes it convenient to require fewer overloaded functions. The order of the arguments needs to be retained, and all the arguments after the ones specified will need to have default values. While this makes a lot of defaulting easy, it still is a little problematic for selectively overriding defaults for only few of the arguments. This is helped by the next feature.\n\n### Arguments can also be named\n\n```kotlin\nfun contrived(first: String = \"First\",\n second: String = \"Second\",\n third: String = \"Third\",\n fourth: String = \"Fourth\",\n fifth: String = \"Fifth\") =\n first + \" \" + second + \" \" + third + \" \" + fourth + \" \" + fifth\n\n// ....\n\nfun someOtherFunction() {\n contrived(second=\"2nd\", fourth=\"4th\")\n // the above returns \"First 2nd Third 4th Fifth\"\n}\n```\n\nAs shown in the example above using a combination of default and named arguments we can choose to have smaller function invocations by specifying only the non defaults. Thus only the arguments whose default values need to be overridden, making the code both terse and more readable\n\n### Functions can have variable arguments\n\n```kotlin\nfun showStrings(suffix: String, vararg items: String) {\n for(item in items) {\n print(item + \" \")\n }\n print(suffix)\n println()\n}\n\nfun somewhereElse() {\n showStrings(\"!\", \"Hello\", \"World\") // prints \"Hello World !\"\n}\n```\n\nFunction can have variable number of arguments so long as all of them are of the same type. The type of the declared argument then becomes an array of that type. Thus in the above example, `items` is an array of String or `Array`.\n\nThe above function also introduces you to a for statement when used with an array. The syntax is very simple and natural, `for itemVar in arrayVar { ... }`\n\n(_I imagine there can be only one `vararg` type argument and that has to be declared at the end but never attempted to do anything differently_)\n\n### Functions can have nested functions\n\n```kotlin\nfun showStrings2(suffix: String, vararg items: String): String {\n val sb = StringBuffer()\n fun appendToBuffer(item: String) {\n sb.append(item)\n sb.append(\" \")\n }\n for(item in items) { appendToBuffer(item) }\n appendToBuffer(suffix)\n return sb.toString()\n}\n\n....\n\nfun somewhereElse() {\n showStrings2(\"!\", \"Hello\", \"World\") // returns \"Hello World !\"\n}\n```\n\nAs shown above, `appendToBuffer` is a nested function (called local function) It can access variables in the parent functions namespace (in the above situation - `sb`.).\n\n### Aside: if - else can also be an expression\n\nIn java, `if`-`else` is a statement. And has a complementary ternary operator `? :` which is an expression. Kotlin merges both by allowing use of `if` - `else` as an expression, and such if/else expressions can be used as a part of the function expression body (or a part of regular block bodies as well). eg.\n\n```kotlin\nfun isBlankString(arg: String) = if (arg.trim() == \"\") true else false\n```\n\nFor an if/else to be an expression, both if and else branches have to be specified and followed by an expression each\n\n### Functions can be tail recursive.\n\nYes! They can be.\n\n```kotlin\nfun factorial(n: Int): Int {\n tailrec fun factorial(accumulator: Int, n: Int): Int = if (n == 1) accumulator else factorial(accumulator * n, n - 1)\n return factorial(1, n)\n}\n```\n\nIf a function is written in a form that lends itself to [tail recursion](https://en.wikipedia.org/wiki/Tail_call) the compiler generates optimised code that uses a loop based version which no longer risks a stack overflow.\n\n### Extension functions.\n\nThis is a very interesting and very useful feature to Kotlin. It is the ability to seemingly externally add a method to a class. Thus the function `isBlankString` introduced above could be rewritten as\n\n```kotlin\nfun String.isBlankString() = this.trim() == \"\"\n\nfun somewhereElse() {\n \" \".isBlankString() // returns true\n}\n```\n\nNote that in an extension function, you can use `this` to refer to the receiver of the function (in this case the String object on whom the `isBlankString` function is called). Also that the receiver class is resolved statically and not dynamically. So if you had an extension function defined for a `Base` class and a `Derived` class that inherits from `Base`, and called it on a variable declared of type `Base` but actually referencing an instance of type `Derived` the `Base` version of the extension function will be called.\n\n### Infix functions\n\nClass member functions or extension functions with a single argument, can in turn be declared as infix which allows from syntactic sugar in terms of how that function is invoked. Thus the function\n\n```kotlin\ninfix fun Int.toThePowerOf(n: Int) = Math.pow(this.toDouble(), n.toDouble()).toInt()\n```\n\ncould be invoked using either of the two ways, the latter becoming feasible only because of the keyword `infix` being used in the function declaration above.\n\n```kotlin\n5.toThePowerOf(3)\n5 toThePowerOf 3\n```\n\n### Higher order functions\n\nHigher order functions are functions which take functions as parameters or as a return type. For that let us first understand how a function can be alternatively represented as a variable using a function type.\n\n```kotlin\nfun double(n: Int) = n * 2\n```\n\nWhat if we wish to represent the function above as a variable. We need to understand the type of the function. In this case it happens to be of the type which takes a single `Int` and returns an `Int`. Knowing that we can now declare it as a variable\n\n```kotlin\nval doubleAsArg = { n : Int -> n * 2}\n```\n\nThe way to invoke the function above would be similar to the way double is invoked\n\n```kotlin\ndoubleAsArg(5) // would return 10\n```\n\nBut the more interesting capability that is now possible is that you can write a function which takes another function as an argument, and in turn pass doubleAsArg as an argument to the newly written function. eg.\n\n```kotlin\nfun twice(function: (Int) -> Int, arg: Int) = function(function(arg))\n\nfun somewhereElse() {\n twice(doubleAsArg,5) // will return 20\n}\n```\n\n`doubleAsArg` could have been also declared using an alternative syntax as follows. For all practical purposes they are identical. However the declaration below makes the function type very explicit (it was inferred in the declaration above)\n\n```kotlin\nval doubleAsArgRedux: (Int) -> Int = { n -> n * 2}\n```\n\n#### Aside: Function Types\n\nJust like `String`, `Int` etc, since functions are also things that can be passed around, they also have types. As is shown above, doubleAsArg above has the type `(Int) -> Int`. In general a function taking n arguments each of type Type1..TypeN, and returning a type TypeReturn will have the type `(Type1, Type2,..TypeN) -> TypeReturn`\n\n### Lambdas\n\nA lambda function is a function that is not declared upfront but is passed in immediately to another function. In the situation below the function that is passed as the first argument to the function twice is a lambda. A lambda expression is always surrounded by curly braces, its parameters (if any) are declared before -> while the body goes after -> (if required).\n\n```kotlin\nfun somewhereElse() {\n twice({n: Int -> n * 10}, 5) // returns 500\n}\n```\n\nNote that for a lambda function the declaration of the parameter types is optional, and there is no way to declare the return type of the function (it has to be inferred). And it is always wrapped with curly braces. Thus the general syntax for a lambda function with n arguments is\n\n```kotlin\n{ p1: Type1, p2: Type2 .. pn: TypeN -> /* do something */ }\n```\n\nNote that the lambda function body is an expression and does not allow a return statement. It could consist of multiple statements and/or branches so long as they end with an expression. So the following is a valid lambda.\n\n```kotlin\n{ n: Int -> val twoN = 2 * n; if (twoN < 100) twoN * 2 else twoN * 3}\n```\n\n### Single parameter lambdas\n\nIf a lambda has a single argument and its type can be inferred, then the argument declaration along with its type and the subsequent `->` can be omitted. In such a case that parameter will have the default name `it`.\n\n```kotlin\nval quadruple: (Int) -> Int = { it * 4}\n```\n\n### Anonymous functions\n\nAn anonymous function is a function with no name. For obvious reasons you cannot declare it by itself. But you could say use it as the right hand side of an assignment to a variable or pass it as an argument to another function eg.\n\n```kotlin\nval triple = fun(n: Int): Int = n * 3\n\nfun somewhereElse() {\n twice(triple, 5)\n twice(fun(n: Int): Int { return n * 3}, 5)\n}\n```\n\nThis is particularly useful when the return type cannot be contextually inferred\n\n### Closures\n\nNote that local functions, lambda functions and anonymous functions can access variables declared in their outer scope, ie. their closure. They can also modify such variables (assuming they are vars).\n\n### Receivers\n\nLambdas and anonymous functions can be used as extension functions as well. Their function type then is `ReceiverType.(p1: Type1 .. pn: TypeN) -> ReturnType`\n\n### Alternative invocation syntax\n\nIf a function has one or more arguments, but exactly one argument which is of a function type, then it can be invoked with an alternative syntax where the function is not specified within the parenthesis, but is instead specified after them wrapped in curly braces.\n\n```kotlin\nfun doubleAndThen(n: Int, then: (Int) -> Int): Int = then(n * 2)\n\nfun somewhereElse() {\n doubleAndThen(5) { it * 5 } // returns 50\n}\n```\n\n### Inline functions\n\nYou can specifically request that a function be inlined using the `inline` keyword. eg. you could've alternatively declared the `doubleAndThen` function above as\n\n```kotlin\ninline fun doubleAndThen(n: Int, then: (Int) -> Int): Int = then(n * 2)\n```\n\nIn this case the compiler will emit the function (and the lambda passed to it) inlined at the call site where doubleAndThen is called. This causes your compiled code to grow in size but could pay off in performance.\n\nIf you do not want a particular lambda passed to the function as inlined, then you could mark it as noinline. eg.\n\n```kotlin\ninline fun doubleAndThen(n: Int, noinline then: (Int) -> Int): Int = then(n * 2)\n```\n\nIf a function is inlined, then the lambdas passed to it are allowed to have a `return`\n\nThe next post in the series is [Exercises in Kotlin: Part 4 - Control flows and return](http://blog.dhananjaynene.com/2016/04/exercises-in-kotlin-part-4-control-flows-and-return/)\n\n","author":"Dhananjay Nene","date":"2016-04-20","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Writing Kotlin Idiomatic Code","url":"http://code.hootsuite.com/writing-kotlin-idiomatic-code/","body":"\n# Writing Kotlin Idiomatic Code\n\n[Kotlin](http://kotlinlang.org/), a new JVM language created by Jetbrains, is quickly becoming the go-to programming language used for Android development at Hootsuite. Its many features and Java interoperability make writing code much faster, cleaner, and less verbose. However, without being aware of language idioms it can be easy to fall back to old Java patterns. In order to maximize the utility of this new language, it is important to familiarize yourself with writing idiomatic Kotlin code. Kotlin’s features, such as the nullable types, lambdas, and delegates, differentiate the language from Java and are useful for writing effective code.\n\n[![Kotlin](http://code.hootsuite.com/wp-content/uploads/2016/08/Kotlin-500x111.png)](https://kotlinlang.org/)\n\n**Null Checks and Safe Casts**\n\nNull references, called a [“billion-dollar mistake”](https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare) by their creator, are a major problem in Java. Null checks are possible in Java, but they are cumbersome, verbose, and easy to miss. In Kotlin, nullability is part of the type system and the language forces null checks for nullable types. The Java way of performing a null check in Kotlin would look like this:\n\n```kotlin\nval school : School = null\n\nif (school != null && school.students != null){\n\tdoSomething(school.students.get(“billy”))\t\n}\n```\n\nFortunately, Kotlin provides a number of easy ways of dealing with this cleanly. The safe call operator “?” provides a simple way of dealing with nullability. When combined with the let{} method, it allows for chained operations like this:\n\n```kotlin\nschool?.students?.let { doSomething(it.get(“billy”)) }\n```\n\nIn the above line of code, the null safety operator used on x and y prevents the code in the let block from being executed if either value is null. When the code in the let block runs it represents the non-null value of y. let blocks can also be useful when needing to access a nullable mutable variable several times since it makes a copy of the variable when it is executed. let blocks can also be used with the safe cast operator in order to replace type checks in if blocks like this:\n\n```kotlin\nif (x is String){\n println(x)\n}\n// can be replaced with\n(x as? String)?.let { println(x) }\n```\n\nFinally, the safe elvis operator that allows you to return an alternative value or throw an error in the case of null:\n\n```kotlin\nval parent = node.getParent() ?: return null\nval name = node.getName() ?: throw IllegalArgumentException(\"...\")\n```\n\n**Lambdas, Closures, and Higher Order Operators**\n\nSome other key features that Kotlin has over Java 7 are lambdas and closures, which allow your code to be more concise and functional. In Kotlin, functions are treated as first class citizens, which means means you can easily pass function parameters without needing to create an interface. For example, the Java way of setting an OnClickListener would look like this:\n\n```kotlin\nsome_view.setOnClickListener(object : View.OnClickListener {\n override fun onClick(view: View) {\n println(\"clicked!\")\n }\n})\n```\n\nUsing lambdas, this can be shorted like this:\n\n```kotlin\nval listener: (View) -> Unit = { println(“clicked!”) }\nsome_view.setOnClickListener (listener)\n\n// Or you can use closures \n\nsome_view.setOnClickListener {doSomething()}\n```\n\nUsing higher order operators and closures, you can remove many loops that you would otherwise need in Java. For example, if one wished to sentence from a list of words with spaces in between one could do the following:\n\n```kotlin\nlistOf(\"This\", \"is\",\"a\", \"sentence\").reduce { accumulator, s -> accumulator +\" \" + s }\n```\n\nIn the above example listOf is used to create an immutable list of words. Then, the reduce operator is used to concat all of the words by accumulating them and appending a space to the end of each word to produce the string “This is a sentence”.\n\nKotlin also allows for higher order operators to be chained. In this more advanced example, this code finds the first perfect square that contains the numbers 123:\n\n```kotlin\n(1..100000).map { it * it }.find { it.toString().contains(Regex(\".*123.*\")) }\n```\n\nIn this example we use the range operator to get a list of numbers, then we map that list to their squares. Afterwards, we use the find operator to find the first number that matches the regular expression. There many more higher order operators that you can read about [here](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/index.html#functions).\n\n**Delegates**\n\nIn Java, if you wish to expose an encapsulated property for a class, you need to write a getter and setter. For example, if you are in a custom view and wish to expose the value of a checkbox, you would need to expose property through a getter and setter. In Kotlin, properties automatically generate getters and setters, so this step is unnecessary. You can delegate out the property of the enclosed checkbox object like this:\n\n```kotlin\nvar isChecked: Boolean by object {\n operator fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {\n return checkbox.checked\n }\n\n operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {\n checkbox.checked = value\n }\n}\n```\n\nThis uses two interesting features of Kotlin: object expressions and property delegates. An anonymous object is created which this property is delegated out to, meaning you can still access it using property access syntax and getters and setters are generated.\n\nAnother problem that delegates can solve is composition. It is often convenient when building a model that depends on views to allow each view to build it’s own component. If you wish to abstract away direct access to the views in this situation, property delegates provide a clean solution. Here’s an example of a class with an EditText view inside it:\n\n```kotlin\nclass EditTextDelegate {\n // represents some editable text view\n var editText: EditText = EditText();\n\n operator fun getValue(thisRef: Any?, property: KProperty<*>): String? {\n return editText.text\n }\n\n operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) {\n editText.text = value\n }\n}\n```\n\nYou can then use your view class as a delegate like this:\n\n```kotlin\nclass ComposedObject(textDelegate: EditTextDelegate){\n var text: String? by textDelegate\n}\n```\n\nThis allows you to ask each of the views that compose this model for their properties without needing to deal with getters and setters. Additionally, you can now access all of these abstracted view properties as if they are normal properties.\n\n**Functions and Functional Programming**\n\nMany of these new Kotlin features mean that functional programming is now an option when solving problems. One of the most important features that Kotlin provides for functional programming is immutability in both default lists and and objects, with it’s val type. In Effective Java Second Edition Joshua Bloch states “Classes should be immutable unless there’s a very good reason to make them mutable.” Many of these same arguments for immutability apply to Kotlin including thread safety, easy shareability, and simplicity. In Kotlin one can define an immutable class like this:\n\n```kotlin\nclass Person(val name: String, val city: String)\n```\n\nWhen functional programming, recursion is key to solving problems without changing state. Recursive functions, however, can be expensive if they aren’t tail recursive because of the stack space required. Kotlin solves this problems with the tailrec operator which optimizes a tail recursive function (a function where the the the last call is recursive) to reuse the stack. For example:\n\n```kotlin\ntailrec fun fib(count: Long, seq: List = listOf(1,1)): List =\nif (seq.size >= count) seq else fib(count, seq + (seq.last() + seq[seq.lastIndex - 1]))\n```\n\nHere we see that the last call in this function is a recursive call, which means that it is able to be optimized. Additionally, in the above function we can see that using operator overloading we are able to use the + operator on the list. This allows for more terse syntax because it returns a new list, not a boolean like List.add() and allows for immutable lists to be used.\n\nMany of the the other parts of the this post such as lambdas and nullable types can be used to enhance functional programming. For more information on functional programming in Kotlin read Mike Hearn’s excellent [blog post](https://medium.com/@octskyward/kotlin-fp-3bf63a17d64a#.geo4mq2nx) goes into more detail.\n\n**Conclusion**\n\nKotlin is language fast growing language, and there are still new practices being developed. Hopefully this blog post provides a clear set of examples of using Kotlin’s feature set more effectively.\n\nThank you to the Android team and Kimli for helping me write and edit this blog post.\n\n","author":"Denis Trailin","date":"2016-08-31","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Introducing Kotlin support in Spring Framework 5.0","url":"https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0","body":"\nFollowing the [Kotlin support on start.spring.io](https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin) we introduced a few months ago, we have continued to work to ensure that Spring and [Kotlin](https://kotlin.link/) play well together. One of the key strengths of Kotlin is that it provides a very good [interoperability](https://kotlinlang.org/docs/reference/java-interop.html) with libraries written in Java. But there are ways to go even further and allow writing fully idiomatic Kotlin code when developing your next Spring application. In addition to Spring Framework support for Java 8 that Kotlin applications can leverage like functional web or bean registration APIs, there are additional Kotlin dedicated features that should allow you to reach a new level of productivity.\n\nThat’s why we are introducing a dedicated Kotlin support in [Spring Framework 5.0 M4](https://spring.io/blog/2016/12/30/spring-framework-5-0-m4-released), and I would like to summarize in this blog post the features that are designed to make your developer experience seamless when using these technologies together. You can use [this link](https://jira.spring.io/issues/?filter=15463) to find Kotlin related issues in Spring Framework bug tracker.\n\nA key building block of our Kotlin support is [Kotlin extensions](https://kotlinlang.org/docs/reference/extensions.html). They allow to extend existing APIs in a non-intrusive way, providing a better alternative to utility classes or Kotlin specific class hierarchies to add Kotlin dedicated features to Spring. Some libraries like [KotlinPrimavera](https://github.com/MarioAriasC/KotlinPrimavera/wiki) from [Mario Arias](https://github.com/MarioAriasC) have already showed various kind of Kotlin helpers we can bring to Spring API in order to allow writing more idiomatic code. With Spring Framework 5, we integrate the most useful and popular extensions in Spring Framework dependencies, and we are adding new ones! Be aware that Kotlin extensions are statically resolved, you have to import them (like static imports in Java).\n\n## Functional bean registration with Kotlin\n\nSpring Framework 5.0 introduces a new way to register beans using lambda as an alternative to XML or JavaConfig with `@Configuration` and `@Bean`. In a nutshell, it makes it possible to register beans with a `Supplier` lambda that acts as a `FactoryBean`.\n\nIn Java you will for example write:\n\n```kotlin\nGenericApplicationContext context = new GenericApplicationContext();\ncontext.registerBean(Foo.class);\ncontext.registerBean(Bar.class, () -> new \n Bar(context.getBean(Foo.class))\n);\n```\n\nWhile in Kotlin, reified type parameters allow us to simply write:\n\n```kotlin\nval context = GenericApplicationContext {\n registerBean()\n registerBean { Bar(it.getBean()) }\n}\n```\n\nYou can see a concrete example of Spring application using both functional [web](https://github.com/mix-it/mixit/blob/master/src/main/kotlin/mixit/controller/UserController.kt) and [bean registration](https://github.com/mix-it/mixit/blob/master/src/main/kotlin/mixit/Context.kt) API at [https://github.com/mix-it/mixit/](https://github.com/mix-it/mixit/).\n\n`ApplicationContext` related Kotlin extensions available are [BeanFactoryExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanFactoryExtensions.kt), [ListableBeanFactoryExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/kotlin/org/springframework/beans/factory/ListableBeanFactoryExtensions.kt), [GenericApplicationContextExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/kotlin/org/springframework/context/support/GenericApplicationContextExtensions.kt) and [AnnotationConfigApplicationContextExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/kotlin/org/springframework/context/annotation/AnnotationConfigApplicationContextExtensions.kt).\n\n## Spring Web functional API, the Kotlin way\n\nSpring Framework 5.0 comes with a `RouterFunctionDsl` that allows you to leverage the [Spring Functional Web API](https://spring.io/blog/2016/09/22/new-in-spring-5-functional-web-framework) recently announced with clean and idiomatic Kotin code:\n\n```kotlin\nfun route(request: ServerRequest) = route(request) {\n accept(TEXT_HTML).apply {\n (GET(\"/user/\") or GET(\"/users/\")) { findAllView() }\n GET(\"/user/{login}\") { findViewById() }\n }\n accept(APPLICATION_JSON).apply {\n (GET(\"/api/user/\") or GET(\"/api/users/\")) { findAll() }\n POST(\"/api/user/\") { create() }\n POST(\"/api/user/{login}\") { findOne() }\n }\n }\n```\n\nThanks to Yevhenii Melnyk for its early prototype and help!\n\n## Leveraging Kotlin nullable information\n\nOriginally based on a community contribution from [Raman Gupta](https://github.com/rocketraman), Spring now takes advantage of [Kotlin null-safety support](https://kotlinlang.org/docs/reference/null-safety.html) to determine if an HTTP parameter is required without having to define explicitly the `required` attribute. That means `@RequestParam name: String?` with be treated as not required and `@RequestParam name: String` as required. This is also supported on Spring Messaging `@Header` annotation.\n\nIn a similar fashion, Spring bean injection with `@Autowired` or `@Inject` uses this information to know if a bean is required or not. `@Autowired lateinit var foo: Foo` implies that a bean of type `Foo` must be registered in the application context while `@Autowired lateinit var foo: Foo?` won’t raise an error if such bean does not exist.\n\n## Extensions for RestTemplate and Functional Web API\n\nFor example, [Kotlin reified type parameters](https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters) provide a workaround for JVM [generics type erasure](https://docs.oracle.com/javase/tutorial/java/generics/erasure.html), so we have introduced some extensions to take advantage of this feature to provide a better API when possible.\n\nThat allows to provide convenient API for `RestTemplate` (thanks to [Jon Schneider](https://github.com/jkschneider) from Netflix for contributing this). For example, to retrieve a list of `Foo` objects in Java you have to write:\n\n```java\nList result = restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference>() { }).getBody();\n```\n\nOr that way if you use an intermediate array:\n\n```java\nList result = Arrays.asList(restTemplate.getForObject(url, Foo[].class));\n```\n\nWhile in Kotlin with Spring Framework 5 extensions you will be able to write:\n\n```kotlin\nval result: List = restTemplate.getForObject(url)\n```\n\nWeb API Kotlin extensions available in Spring Framework 5.0 are [RestOperationsExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/kotlin/org/springframework/web/client/RestOperationsExtensions.kt), [ServerRequestExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-web-reactive/src/main/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensions.kt), [BodyInsertersExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-web-reactive/src/main/kotlin/org/springframework/web/reactive/function/BodyInsertersExtensions.kt), [BodyExtractorsExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-web-reactive/src/main/kotlin/org/springframework/web/reactive/function/BodyExtractorsExtensions.kt), [ClientResponseExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-web-reactive/src/main/kotlin/org/springframework/web/reactive/function/client/ClientResponseExtensions.kt), [ModelExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/kotlin/org/springframework/ui/ModelExtensions.kt) and [ModelMapExtensions](https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/kotlin/org/springframework/ui/ModelMapExtensions.kt).\n\nThese extensions also provide member functions supporting natively Kotlin `KClass`, allowing you to specify `Foo::class` parameter instead of `Foo::class.java`.\n\n## Reactor Kotlin extensions\n\n[Reactor](https://projectreactor.io/) is the reactive foundation Spring Framework 5.0 is built upon, and there are good chances you are going to use its [Mono](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html), [Flux](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html) and [StepVerifier](https://projectreactor.io/docs/test/release/api/reactor/test/StepVerifier.html) APIs when developing a reactive web application.\n\nSo today we are also introducing Kotlin support in Reactor, via the new [reactor-kotlin](https://github.com/reactor/reactor-kotlin) project! It provides extensions to be able to create `Mono` instances from any class instance by writing `foo.toMono()` which many will prefer to `Mono.just(foo)`. It also supports for example creating a `Flux` from a Java 8 `Stream` instance with `stream.toFlux()`. `Iterable`, `CompletableFuture` and `Throwable` extensions as well as `KClass` based variants of Reactor API are also provided.\n\nThis is still the early days of this project, so feel free to [contribute](https://github.com/reactor/reactor-kotlin/pulls) your own extensions if you find missing bits.\n\n## No need to declare your bean class as open anymore\n\nUntil now, one of the few pain points you faced when building a Spring Boot application with Kotlin was the need to add an `open` keyword on each class and their member functions of Spring beans proxified with CGLIB like `@Configuration` classes. The root cause of this requirement comes from the fact that in Kotlin, [classes are final by default](https://discuss.kotlinlang.org/t/classes-final-by-default/166).\n\nFortunately, Kotlin 1.0.6 now provides a `kotlin-spring` plugin that open classes and their member functions by default for classes annotated or meta-annotated with one of the following annotation:\n\n* `@Component`\n* `@Async`\n* `@Transactional`\n* `@Cacheable`\n\nMeta-annotations support means that classes annotated with`@Configuration`, `@Controller`, `@RestController`, `@Service` or `@Repository` are automatically opened since these annotations are meta-annotated with `@Component`.\n\nWe have updated [start.spring.io](http://start.spring.io/#!language=kotlin) to enabled it by default. You can have a look to [this Kotlin 1.0.6 blog post](https://blog.jetbrains.com/kotlin/2016/12/kotlin-1-0-6-is-here/) for more details, including the new `kotlin-jpa` and `kotlin-noarg` plugins really useful with Spring Data entities.\n\n## Kotlin based Gradle build configuration\n\nBack in May, Gradle [announced](https://blog.gradle.org/kotlin-meets-gradle) that they are going to support writing build and config files in Kotlin in addition to Groovy. This makes it possible to have full auto-completion and validation in your IDE, because such files are regular statically-typed Kotlin Script files. This is likely to become the natural choice for Kotlin based project, but this is also valuable for Java projects too.\n\nSince May, the [gradle-script-kotlin](https://github.com/gradle/gradle-script-kotlin) project has continued to evolve, and is now usable with 2 warnings to keep in mind:\n\n* You need Kotlin 1.1-EAP IDEA plugin to get autocompletion (but wait Kotlin `1.1-M05` if you are using `kotlin-spring` plugin since `1.1-M04` does not work reliably with this plugin yet)\n* The documentation is not complete, but the Gradle team is really helpful on the #gradle channel of the Kotlin Slack.\n\nBoth [spring-boot-kotlin-demo](https://github.com/sdeleuze/spring-boot-kotlin-demo) and [mixit](https://github.com/mix-it/mixit/) projects use such Kotlin based Gradle builds, so feel free to have a look. We are [discussing](https://github.com/spring-io/initializr/issues/334) adding such support on start.spring.io.\n\n## Kotlin Script based templates\n\nAs of version 4.3, Spring Framework provides a [ScriptTemplateView](http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html) to render templates using script engines that supports [JSR-223](https://www.jcp.org/en/jsr/detail?id=223). Kotlin 1.1-M04 provides such support and allows to render Kotlin based templates, see [this commit](https://github.com/spring-projects/spring-framework/commit/badde3a479a53e1dd0777dd1bd5b55cb1021cf9e) for details.\n\nThis enables some interesting use cases like writing type-safe templates using [kotlinx.html](https://github.com/Kotlin/kotlinx.html) DSL or simply Kotlin multiline `String` with interpolation, as demonstrated in this [kotlin-script-templating](https://github.com/sdeleuze/kotlin-script-templating) project. This could allow you to write this kind of templates with full autocompletion and refactoring support in your IDE:\n\n```kotlin\nimport io.spring.demo.User\nimport io.spring.demo.joinToLine\n\n\"\"\"\n${include(\"header\", bindings)}\n

    Title : $title

    \n
      \n ${(users as List).joinToLine{ \"
    • User ${it.firstname} ${it.lastname}
    • \" }}\n
    \n${include(\"footer\")}\n\"\"\"\n```\n\nThis feature is still work in progress, but I am collaborating with the Kotlin team to tentatively make it production ready with nested template and i18n support on both MVC and Reactive sides for Spring Framework 5.0 GA.\n\n## Conclusion\n\nThe more I write Spring Boot applications with Kotlin, the more I feel these 2 technologies share the same mindset and allow you to write applications more efficiently with expressive, short and readable code, and Spring Framework 5 Kotlin support is a significant step towards combining these technologies in a natural, simple and powerful way.\n\nKotlin can be used to write [annotation-based Spring Boot applications](https://github.com/sdeleuze/spring-boot-kotlin-demo), but will also be a good fit with the new kind of [functional and reactive applications](https://github.com/mix-it/mixit/) that Spring Framework 5.0 will enable.\n\nKotlin team did a great job by fixing almost all the pain points we reported, so big thanks to them. The upcoming Kotlin 1.1 release is expected to also fix [KT-11235](https://youtrack.jetbrains.com/issue/KT-11235) in order to allow specifying array annotation attribute single value without `arrayOf()`. The main remaining issue you will face is maybe [KT-14984](https://youtrack.jetbrains.com/issue/KT-14984) that will require specifying explicitly lambda type where just specifying `{ }` should be enough.\n\nFeel free to test Spring Framework 5.0 Kotlin support by going to [start.spring.io](https://start.spring.io/#!language=kotlin) and generating a Spring Boot `2.0.0 (SNAPSHOT)` project and send us your feedback here or in the `#spring` channel of [Kotlin Slack](http://slack.kotlinlang.org/). You can also [contribute](https://github.com/spring-projects/spring-framework/pulls) the Kotlin extensions you need ;-)\n\n","author":"Sébastien Deleuze","date":"2017-01-04","type":"article","categories":["Kotlin","Spring"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Non-trivial constructors in Kotlin","url":"http://alexshabanov.com/2014/12/01/non-trivial-constructors-in-kotlin/","body":"\nKotlin really simplifies things such as defining constructors and writing immutable objects for your application. For example, flexible Kotlin constructor definitions eliminate the need of [builder classes](http://en.wikipedia.org/wiki/Builder_pattern \"Builder Pattern - Wikipedia\") (you simply don’t need them in 99% of all the possible use cases, if you use Kotlin), thus reducing overhead of having immutable objects in your application, while retaining full flexibility and expressiveness.\n\nHowever, if you want to define non-trivial constructor (especially for [data classes](http://kotlinlang.org/docs/reference/data-classes.html \"Kotlin Data Classes\")) it might not be as trivial as just writing a function.\n\nFor example, when I started playing with Kotlin, I decided to start with something as simple as defining a class that would represent a [rational number](http://en.wikipedia.org/wiki/Rational_number \"Rational Number - Wikipedia\").\n\nMy first brute force (or naive, if you like) attempt to define that class was as follows:\n\n```kotlin\ndata class Ratio (val numerator : Int, val denominator : Int)\n```\n\nThe problems with this class are obvious: you can create ratios like Ratio(1, 2) and Ratio(2, 4) and they won’t be equal to each other. And I wanted exact opposite – whenever the user of this class constructs a ratio it divides a numerator and denominator to their greatest common divisor – to have coprime numerator and denominator in the corresponding fields of the newly constructed instance of Ratio class. Also I wanted to retain nice-to-have features of the [data class](http://kotlinlang.org/docs/reference/data-classes.html \"Kotlin Data Classes\") – I didn’t want to define copy, hashCode and equals myself.\n\nSo, at this point you’re welcome to play before reading my solution.\n\n* * *\n\nOK, now if you came up with your approach or just would like to see the possible solution – here is the [link to the full class definition](https://github.com/avshabanov/math/blob/master/approx/src/main/kotlin/ratio.kt \"Ratio class definition in Kotlin\") for those who interested.\n\nIn short: you can define custom class constructor (and yet retain call semantics) is to define `invoke` function in ‘class object’ section of your class that has special semantics: you can define static functions as well as factory function `invoke`. It may look as follows (simplified):\n\n```kotlin\nclass Ratio private (val numerator : Int, val denominator : Int) {\n class object {\n val ZERO = Ratio(0, 1) // static member!\n val ONE = Ratio(1, 1) // static member!\n fun invoke(numerator : Int = 1, denominator : Int = 1) : Ratio {\n if (denominator == 0) throw IllegalArgumentException(\"denominator can't be zero\")\n if (numerator == 0) return ZERO\n if (numerator == denominator) return ONE\n\n val d = gcd(numerator, denominator)\n return Ratio(numerator / d, denominator / d)\n } // <-- end of static function invoke\n\n fun gcd(a : Int, b : Int) : Int { /*omitted*/ } // static function!\n }\n\n}\n```\n\nThe beauty of Kotlin here is that you'll still be able to use 'constructor' semantics whenever you need to create an instance of `Ratio`, i.e. you can write as follows as if you had ordinary constructor:\n\n```kotlin\nval r1 = Ratio(3, 7) // invoke will be called here\nval r2 = Ratio(numerator = 1, denominator = 4) // invoke will be called here\n```\n\nThis is it, I hope you find it useful.\n\n","author":"Alex Shabanov","date":"2014-12-01","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Our Experiment Building a Multiselection Solution for Android in Kotlin","url":"https://yalantis.com/blog/how-we-created-a-multiselection-solution-for-android/","body":"\n“Multiselection can be quite tricky on mobile,” says our designer, Vitaly Rubtsov. Multiselection solutions found in most applications – Telegram, Apple Music, Spotify and others – are usually not that flexible and can be quite uncomfortable to use.\n\nWhen creating your own playlists in Apple Music, for example, it can be confusing to understand which songs have already been added without switching between several screens or endlessly scrolling through a list of selected songs.\n\nAnd the situation may get even worse if we decide to apply filters. In this case, the list of compositions may change once we’ve applied a filter, but the compositions you’ve already selected may not be displayed at all. Vitaly decided to solve this problem with his own concept for multiselection (originally published to [Dribbble](https://dribbble.com/shots/2904577-Multi-Selection-Experiment)).\n\nThe idea is just brilliant: the screen is divided into two parts, so you can always “see and manage what you’ve selected without having to leave the current view,” as Vitaly explains. Filters are only applied to the main list from which you select, but are not applied to your list of selected items.\n\nThat's when I knew that Vitaly’s multiselection concept must be brought to life by any means; so I started my work on the component almost immediately. And now let’s see how the Android Multiselection Animation was born.\n\n![](https://lh6.googleusercontent.com/yIkYWeVg0xYmKOWMEMlUn1hRk2B2DBjeD14bqTRS5cbsRYyLKpvkJ6bPg-vUbQjyCaVHsCahYEXQfM_2RCj-d1x0dcqfPZ34XKX3cMF0k2Vfr5ktrQrmpTqYHwA12LXm8ESxsmSj)\n\n## Implementing the component\n\nThe animation’s logic seems straightforward, yet it has a few catches.\n\nThe component has a `ViewPager` with two `RecyclerViews`. We can make a `ViewPager` page narrower than the screen by overriding the `getPageWidth` method in the `ViewPager` adapter and returning a floating number between 0 and 1.\n\nA `ViewPager` has two pages, each with the `RecyclerView`. Unselected items are on the left list. Selected items are on the right one. For instance, if you click an unselected item, a few things will happen:\n\n1. The clicked item is deleted from the unselected items list and added to the container that holds both lists.\n\n2. Item position in the selected items list is determined. (The unselected list always has its items sorted alphabetically. The selected list has its items in the order they were selected)\n\n3. A hidden item is added to the selected items list.\n\n4. The translation animation is run for the clicked item.\n\n5. The clicked item is deleted and the hidden item in the selected list is shown.\n\nThe most tricky part of this sequence is removing a view from the layout manager; otherwise, the layout manager will try to recycle it, which will cause an error since we are deleting the view from `RecyclerView`:\n\n sourceRecycler.layoutManager.removeViewAt(position)\n\n## Technology stack\n\nI chose the Kotlin programming language as the tool for this job. The main benefits of Kotlin are its concise syntax and virtually no `NullPointerException` crashes compared to Java. (And, as a result, Kotlin makes for happier developers.) Here are a few useful Kotlin features that made my life easier while I was implementing this library:\n\n### Extension functions\n\nWith extension functions, you can ‘extend’ pre-defined classes with useful methods – even classes you don’t own!\n\nTake the Android View class, for example. Often you need to remove a view from its old parent and attach it to a new one:\n\n```kotlin\n​fun View.removeFromParent() {\n val parent = this.parent\n if (parent is ViewGroup) {\n parent.removeView(this)\n }\n}\n```\n\nAfter defining the above method, you can now call it from anywhere in your project like this:\n\nOr, you can even write a method that removes the view from its current parent and attaches the view to a new one:\n\n```kotlin\nview.attachTo(newParent)\n```\n\nOne more advantage is that you can add the (strangely absent) `setScaleXY `method. I’ve hardly ever seen `setScaleX` used without `setScaleY`, or vice versa. So why not have a single method that sets both scales? Let’s do it:\n\n```kotlin\nfun View.setScaleXY(scale: Float) {\n scaleX = scale\n scaleY = scale\n}\n```\n\nYou can find more examples of how we used extension functions in the Extensions.kt file in the library’s source code.\n\n### Null safety\n\nKotlin’s null safety feature is a game changer. The ‘?.’ operator works just like ‘.’ but if the object it’s called upon is null, ‘?.’ won’t throw a `NullPointerException`, but will return null instead:\n\n```kotlin\nvar targetView: View? = targetRecycler.findViewHolderForAdapterPosition(prev)?.itemView\n```\n\nThe code above, for instance, won’t crash even if `findViewHolderForAdapterPosition` returns null.\n\n### Collections\n\nKotlin comes with `stdlib`, which includes a lot of neat collection functions like map and filter. These methods are widespread, and basically exhibit the same behavior across programming languages, including Java 8 (streams). Unfortunately, streams are still not available out of the box for Android development.\n\nFor our multiselection library, we needed to animate transparency of every view child except the child with a specific id. The following Kotlin code does the job well:\n\n```kotlin\nif (view is ViewGroup) {\n (0..view.childCount - 1)\n .map { view.getChildAt(it) }\n .filter { it.id != R.id.yal_ms_avatar }\n .forEach { it.alpha = value }\n}\n```\n\nAccomplishing the same in Java would take perhaps twice as many lines of code as we used here.\n\n* ### Better syntax\n\nIn general, Kotlin’s syntax is more concise and readable than Java’s.\n\nOne example is the when expression. Unlike switch (Java’s analogue), Kotlin’s when expression returns a value, so you have to assign it to a variable or return it from a function. That feature in and of itself allows for shorter and more readable code:\n\n```kotlin\nprivate fun getView(position: Int, pager: ViewPager): View = when (position) {\n 0 -> pageLeft\n 1 -> pageRight\n else -> throw IllegalStateException()\n}\n```\n\n## How to use MultiSelect\n\nHere are 5 simple steps to follow if you want to use our multiselect component in your project.\n\n1. First, add this to your root build.gradle:\n\n```gradle\nallprojects {\n repositories {\n ...\n maven { url \"https://jitpack.io\" }\n }\n}\n```\n\nAnd then add this to your module `build.gradle`:\n\n```gradle\ndependencies {\n compile 'com.github.yalantis:multi-selection:v0.1'\n}\n```\n\n2. Then create a `ViewHolder`:\n\n```javas\nclass ViewHolder extends RecyclerView.ViewHolder {\n TextView name;\n TextView comment;\n ImageView avatar;\n\n public ViewHolder(View view) {\n super(view);\n name = (TextView) view.findViewById(R.id.name);\n comment = (TextView) view.findViewById(R.id.comment);\n avatar = (ImageView) view.findViewById(R.id.yal_ms_avatar);\n }\n\n public static void bind(ViewHolder viewHolder, Contact contact) {\n viewHolder.name.setText(contact.getName());\n viewHolder.avatar.setImageURI(contact.getPhotoUri());\n viewHolder.comment.setText(String.valueOf(contact.getTimesContacted()));\n }\n}\n```\n\nTake note of the static bind method. It’s useful to have it in here because that way you can use the same viewholder in both adapters.\n\n3. Next, create two adapters for unselected and selected items. The first one should extend `BaseLeftAdapter`; the second, `BaseRightAdapter`:\n\n```java\n​public class LeftAdapter extends BaseLeftAdapter{\n\n private final Callback callback;\n\n public LeftAdapter(Callback callback) {\n super(Contact.class);\n this.callback = callback;\n }\n\n @Override\n public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false);\n return new ViewHolder(view);\n }\n\n @Override\n public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {\n super.onBindViewHolder(holder, position);\n\n ViewHolder.bind(holder, getItemAt(position));\n\n holder.itemView.setOnClickListener(view -> {\n // ...\n callback.onClick(holder.getAdapterPosition());\n // ...\n });\n\n }\n\n}\n```\n\nNotice that you should call super constructor with the model class you use in the adapters.\n\nThe adapter for selected items is very similar:\n\n```java\npublic class RightAdapter extends BaseRightAdapter {\n\n private final Callback callback;\n\n public RightAdapter(Callback callback) {\n this.callback = callback;\n }\n\n @Override\n public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false);\n return new ViewHolder(view);\n }\n\n @Override\n public void onBindViewHolder(@NotNull final ViewHolder holder, int position) {\n super.onBindViewHolder(holder, position);\n\n ViewHolder.bind(holder, getItemAt(position));\n\n holder.itemView.setOnClickListener(view -> {\n // ...\n callback.onClick(holder.getAdapterPosition());\n // ...\n });\n }\n}\n```\n\nAdapters need to extend different base classes because unselected items are sorted, but selected items stay in the order they were previously selected.\n\n4. Finally, call the builder:\n\n```java\nMultiSelectBuilder builder = new MultiSelectBuilder<>(Contac\n .withContext(this)\n .mountOn((ViewGroup) findViewById(R.id.mount_point))\n .withSidebarWidth(46 + 8 * 2); // ImageView width with paddings\n```\n\nYou’ll then need to:\n\n* Pass the context.\n* Pass the view (usually `FrameLayout`) that you want the component to be mounted on.\n* Specify the sidebar width in dp (shown in the image below).\n\n![how-we-build-a-multiselection-component-for-android-application](http://images.yalantis.com/w770/uploads/ckeditor/pictures/2105/content_Artboard.jpg)\n\n5. Last but not least, set the adapters:\n\n```java\nLeftAdapter leftAdapter = new LeftAdapter(position -> mMultiSelect.select(position));\nRightAdapter rightAdapter = new RightAdapter(position -> mMultiSelect.deselect(position));\n\nleftAdapter.addAll(contacts);\n\nbuilder.withLeftAdapter(leftAdapter)\n .withRightAdapter(rightAdapter);\n```\n\nNow all you need to do is call `builder.build()`, which returns the `MultiSelect` instance.\n\nYou can find this MultiSelect library and many more in our GitHub repository, and can check out our designs on Dribbble:\n\n* [GitHub](https://github.com/Yalantis/Multi-Selection)\n\n* [Dribbble](https://dribbble.com/shots/2904577-Multi-Selection-Experiment)\n\nYou can also get a cool demo with our component on [Google Play Store](https://play.google.com/store/apps/details?id=com.yalantis.multiselect.demo).\n\n","author":"Artem Kholodnyi","date":"2016-11-03","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The Next Language You Thought You Didn’t Need","url":"http://www.dellingertechnologies.com/2016/08/17/kotlin-the-next-language-you-thought-you-didnt-need/","body":"\nAt a recent conference, I happened upon some information about the programming language, Kotlin. I had heard of it, but never looked into anything about it. After taking a casual look at it, I’m strongly considering giving it a shot on a “real” project. Read on to find out why. My background is primarly Java programming, followed closely by Ruby. I’ve had experience with numerous other languages over the years, but usually only on a small number of projects, or on projects old enough that I don’t consider myself current. Java is my favorite overall. Ruby has lots of great benefits in certain types of projects, so it’s a handy tool to have around as well. So what about Kotlin?\n\nKotlin was developed by JetBrains, the makers of IntelliJ IDEA and other IDE variants as well as other developer tools. Kotlin is a statically typed language that runs on the Java Virtual Machine. It is not syntax compatible with Java, but both Java and Kotlin source files can seamlessly interoperate within the same code base. That is a pretty huge benefit if you’d like to try it out in an existing Java project and can not afford to spin up an entirely new rewrite. The language was first announced in 2011 and was open sourced in 2012. The version 1.0 release became available earlier this year. The language supports object oriented and procedural programming. And, like Scala, it tackles many of the shortcomings and inconveniences from Java. For example, Kotlin makes a distinction between nullable and non-nullable types, so you must explicitly indicate that variables can be null. It allows you to write concise, clear code and reduce lots of boilerplate which is often a big complaint with Java.\n\nSo why not just use Scala? In my case, a language needs to really sell me on the benefits and low cost of adoption for it to be worth my time to consider incorporating it into my toolset. Scala just never seemed convenient enough in my cursory glances at it. But Kotlin seems to have knocked down those barriers to entry. It has fantastic tool support in IntelliJ. You can even have the IDE automatically convert Java code to Kotlin if you want. Since Kotlin source code is perfectly happy to live alongside Java code, it is trivial to transition at your own pace or give it a trial run without too much overhead. You can call any existing Java code directly and easily from Kotlin code and vice versa. Kotlin is even quickly gaining ground as a go to platform for Android development.\n\nAt this point, I’ve only looked at a few tutorial examples to start getting my feet wet, so I can’t speak to the long term transition and adoption. However, it was ridiculously easy to get started and that is a serious win in my book. I enjoyed it enough to actually take a look at using it on some upcoming personal projects. I’m interested to see how it plays alongside some of my goto Java frameworks like Spring Boot, etc., although it will almost certainly be pretty seamless. JetBrains has committed to long term support of the language so it’s not going away anytime soon.\n\nI’m not one to jump over to the latest and greatest languages that show up on the radar. They usually turn out to be more effort than they are worth for me. However, Kotlin has definitely piqued my interest and I will be taking a closer look at how I can incorporate it my projects. Great benefits to efficiency, low barriers to entry, and low risk. With features like that, if you are a Java developer, it might be a language you are interested in as well. If you’ve tried it already, let me know about your experiences with it.\n\n","author":"Jay Dellinger","date":"2016-08-17","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin/Native Tech Preview: Kotlin without a VM","url":"https://blog.jetbrains.com/kotlin/2017/04/kotlinnative-tech-preview-kotlin-without-a-vm/","body":"\nWe are happy to announce the first Technology Preview of **Kotlin/Native** that compiles Kotlin directly to machine code. The Kotlin/Native compiler produces standalone executables that can run without any virtual machine.\n\nIt is not a fully functional release yet, but you can already play with the technology and take a look at its source code [here][]. The compiler is available under the Apache 2 OSS license.\n\n![KotlinNative][]\n\n\n## Mission ##\n\nKotlin/Native is another step toward making Kotlin usable throughout a modern application. Eventually, it will be possible to use Kotlin to write every component, from the server back-end to the web or mobile clients. Sharing the skill set is one big motivation for this scenario. Another is sharing actual code.\n\nOur vision for inter-platform code reuse is the following: one can write entire modules in Kotlin in a platform-independent way and compile them for any supported platform (currently these are Kotlin/JVM, Kotlin/JS and the upcoming Kotlin/Native). We call these *common modules*. Parts of a common module may require a platform-specific implementation, which can be developed individually for each platform. Common modules provide a common API for all clients, but other (platform-specific) modules can extend this API to provide some exclusive capabilities on their platform.\n\nNote that we do not intend to make arbitrary Kotlin/JVM programs runnable on Kotlin/Native or Kotlin/JS. It would be equivalent to implementing another JVM, which is both a lot of work and a lot of limitations for the runtime. We are going another way: providing a common language for all platforms while enabling creation of common libraries through seamless interoperability with platform code.\n\n## Technology ##\n\nKotlin/Native uses the LLVM compiler infrastructure to generate machine code. In this preview, we support the following [target platforms][]:\n\n * Mac OS X 10.10 and later (x86-64)\n * x86-64 Ubuntu Linux (14.04, 16.04 and later), other Linux flavours may work as well\n * Apple iOS (arm64), cross-compiled on MacOS X host\n * Raspberry Pi, cross-compiled on Linux host\n\nMore platforms can be added relatively easily, as long as the LLVM support is available for them. We will probably support a few more platforms out-of-the-box in the future.\n\nAs usual, interoperability is among our top priorities, and Kotlin/Native can efficiently call C functions and pass/get data to/from them. You can generate Kotlin bindings from a C header files at build time and get fast type-safe access to any API native to the target platform. See detailed instructions [here][here 1].\n\n### Memory management ###\n\nKotlin/Native is designed to potentially enable different memory management solutions for different target platforms. For example, in the future it may make sense to have a tracing GC for server/desktop platforms, while ARC makes a lot more sense on iOS. Some platforms may only need manual memory management, and get an even smaller Kotlin/Native runtime in return.\n\nThis Technology Preview features automatic reference counting with a cycle collector on top, but what the final memory management solution(s) will look like is unknown at this point.\n\n### Current limitations ###\n\nAs mentioned above, Kotlin/Native is far from complete, so this Technology Preview has a number of limitations that will be eliminated at later stages:\n\n * No performance optimization has been done yet, so benchmarking Kotlin/Native makes no sense at this point.\n * The Standard Library and reflection support are far from complete, more APIs will be added later.\n * Read more in the [Release Notes][].\n\n## Future plans ##\n\nWe are currently working on the core technology for Kotlin/Native which is the same for all target platforms (compiler, core runtime and library). As a matter of possible future work, we are considering the following possible use cases:\n\n * iOS applications (reusing code with Android)\n * Embedded systems/IoT (e.g., Arduino and beyond)\n * Data analysis and Scientific Computing\n * Server-side and Microservices (low-footprint executables, utilizing the power of coroutines)\n * Game Development\n\n## How to try ##\n\nWe’ve prepared two archives with compiler, samples and documentation: [for Mac and iOS][] and [for Linux and Raspberry Pi][].\n\nCheck out the [Github project][] and [Release Notes][] for instructions.\n\n**Your feedback is very welcome** in the \\#kotlin-native channel on our [public Slack][] (Get your invite [here][here 2].\n\n[here]: https://github.com/JetBrains/kotlin-native/\n[KotlinNative]: https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2017/04/KotlinNative.png\n[target platforms]: https://github.com/JetBrains/kotlin-native/blob/v0.1.0/RELEASE_NOTES.md#supported-platforms\n[here 1]: https://github.com/JetBrains/kotlin-native/blob/v0.1.0/INTEROP.md\n[Release Notes]: https://github.com/JetBrains/kotlin-native/blob/v0.1.0/RELEASE_NOTES.md\n[for Mac and iOS]: http://download.jetbrains.com/kotlin/native/kotlin-native-macos-0.1.tar.gz\n[for Linux and Raspberry Pi]: http://download.jetbrains.com/kotlin/native/kotlin-native-linux-0.1.tar.gz\n[Github project]: https://github.com/JetBrains/kotlin-native\n[public Slack]: https://kotlinlang.slack.com/\n[here 2]: http://slack.kotl.in/\n","author":"Andrey Breslav","date":"2017-04-04","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1 Event Report","url":"https://blog.jetbrains.com/kotlin/2017/04/kotlin-1-1-event-report/","body":"\nThe Kotlin 1.1 release was warmly met by the community. To demonstrate the new features in Kotlin 1.1, JetBrains offered an online event. All those interested were able to watch a live stream of Andrey Breslav’s demo presentation and get their questions answered during a Q&A session.\n\nThis motivated many local communities to meet up: more than 30 user groups hosted events in 21 countries.\n\nYou can find the full list of the events at [the Kotlin community web page][]. Over 3000 people joined the broadcast on the day of the event.\n\nThe recording of the demo presentation and the Q&A is available on YouTube:\n\n\n\n## Kotlin 1.1 Event Feedback ##\n\nIf you watched the live stream, we want to know what you think! Please share your feedback by [completing this form][]. It should only take about 7-10 minutes. Your input is very important in helping us improve all future Kotlin events.\n\n## Kotlin Future Features Survey ##\n\n![future\\_features\\_collage\\_2][future_features_collage_2]\nWe also offered all communities to make an impact on Kotlin future. Event organizers received survey kits and event participants could have a say on the most expected features in an off-line mode. The survey gained much attention, and we’ve now placed it online to listen to the wider community. Now you can [have your say on the Kotlin future][] online!\n\nPlease note it’s more likely that you won’t see those features in v1.2, but we will take your opinion into account when prioritizing our work.\n\n[the Kotlin community web page]: http://kotlinlang.org/community/talks.html?time=kotlin\n[completing this form]: https://docs.google.com/forms/d/e/1FAIpQLSdgKsJzwc1ToAusi-xpEiiE1O4t3HA5xjlbZXDU5Mg0i3qvNg/viewform\n[future_features_collage_2]: https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2017/04/collage_2.png\n[have your say on the Kotlin future]: https://docs.google.com/forms/d/e/1FAIpQLSdnCgBonEV5pwN8L903BzdYb9Baf0dpwsJ5YrKnxLveiLFkEQ/viewform\n","author":"Alina Dolgikh","date":"2017-04-06","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Quick dive in Kotlin extensions","url":"https://medium.com/@piotr.slesarew/quick-dive-in-kotlin-extensions-317eda4d0c0d#.vulwu13rs","body":"\n> Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. _— (GoF)_\n\nAs a kid, I was a fan of diving as it gave me freedom and measureless joy. Over the years my passion changed and I have started diving in deep waters of the ocean of programming. Knowing how things work brings a lot of satisfaction so let’s try to understand amazing extensions in Kotlin.\n\nIt is said that problems with architecture design are strictly connected with lack of knowledge about how language mechanisms work and what they are for. Sadly but truly nowadays countless amount of engineers have gaps in fundamentals and that is why we need to evangelize them over and over again.\n\n#### What are extensions for?\n\nKotlin introduces extension functions and extension properties to solve some common scenarios. Imagine that there is a need to add or extend existing functionality to a class. What are the options?\n\n* Extend an entire class\n* Use util function\n* Decorate\n\nExtending a class is always a risky option, util function will become a big static pain for testing and even using sophisticated Decorator Pattern(if applicable) generates tons of boilerplate. Kotlin extensions give the fourth and the best option you can get.\n\n#### Extend non-extendable\n\nExtension mechanism provides an ability to add functionality even to final classes. Let’s have a look at this code.\n\n```kotlin\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\n\nfun String.removeWhitespaces() = replace(\" \", \"\")\n\nclass StringKtTest {\n @Test fun removesWhitespacesFromString() {\n val tested = \"Piotr Slesarew\"\n\n val actual = tested.removeWhitespaces()\n\n val expected = \"PiotrSlesarew\"\n assertEquals(expected, actual)\n }\n}\n```\n\nFrom the newbie perspective, it looks pretty odd. Adding functionality to String class? How is that even possible? Extensions do not actually modify classes they extend.\n\n```kotlin\npublic final class StringKtTestKt {\n @NotNull\n public static final String removeWhitespaces(@NotNull String $receiver) {}\n}\n```\n\nThe sample above shows that compiler generates a class and the static function with a receiver as a parameter. The receiver has a type of extended class. Now it is obvious why the code is so awful when extension functions are used in Java. In the end, they are only static functions.\n\n```kotlin\nString foo = \"Piotr Slesarew\";\nStringKtTestKt.removeWhitespaces(foo);\n```\n\n#### Inlining matters\n\nInline functions are extremely beneficial in case of a having function that takes functions as parameters. That sounds like an inception but do not be frightened. It is just a functional programming and it is closely related to extension functions.\n\nLately, I was dealing a lot with collections and for most of the time, I had to search through them in reverse order. My pre-refactored code looked like this.\n\n```kotlin\nval collection = listOf(\"Piotr\", \"Slesarew\")\n\ncollection.reversed()\n .forEach(::println)\n```\n\nAs soon as I typed ._reversed().forEach()_ twentytimes I realized that it is a really good idea to squash it into ._reversedForEach(). R_efactored code used extension function which I added to _Iterable_ type.\n\n```kotlin\nval collection = listOf(\"Piotr\", \"Slesarew\")\n\ncollection.reversedForEach(::println)\n\nfun Iterable.reversedForEach(action: (T) -> Unit): Unit {\n for (element in this.reversed()) action(element)\n}\n```\n\nEverything was great except a performance. I accidentally forgot to _inline_ my function so my code was creating redundant objects. This is a common mistake in designing extension functions.\n\n![](https://cdn-images-1.medium.com/max/800/1*5Wsah0hFTzI4-a0MYBgOoA.png)\n_**Left:** no inlining | **Right:** with inlining_\n\nThe picture shows Java code generated from Kotlin. It is clear that _inlining_ has a great impact on bytecode. For the closer look, I suggest to read carefully _inline functions_ section in Kotlin reference and play with some samples.\n\nSumming up extension functions have a great potential to cure a lot of headaches but it needs to be remembered that with a great power comes a great responsibility so use them consciously.\n\n_If this was interesting to you, please do hit the heart button ❤ or_ [_let me know on Twitter_](https://twitter.com/SliskiCode)_._\n\n","author":"Piotr Ślesarew","date":"2016-11-05","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Coding Functional Android Apps in Kotlin: Getting Started","url":"https://code.tutsplus.com/tutorials/start-developing-android-apps-with-kotlin-part-1--cms-27827","body":"","author":"Jessica Thornsby","date":"2016-12-19","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Decision Trees with Kotlin","url":"http://cloudmark.github.io/Decision-Trees/","body":"\n\nIt has been quite a while since my last post; things have been pretty busy in preparation for the launch of our new product [VoodooDreams](https://www.voodoodreams.com). Now that we have shipped our baby, I am super eager to try out [Kotlin](https://www.kotlin.com) - a new programming language from JetBrains targeting the JVM. One interesting aspect about Kotlin (similar to Scala and other JVM-based languages) is that it treats functions as first class citizens (_IMO Functional Interfaces just patch the gap_). In order to try out this language we will create a Decision Tree Learning algorithm which is one of the most used and practical methods for learning inductive inference. \n\n# Learning as a Task\nIn order to ground our discussion, we will consider the example of learning the concept \"Play Tennis\". _Note that this example has been adapted from the book - [Machine Learning by Tom Mitchell](https://www.amazon.de/Machine-Learning-McGraw-Hill-Computer-Science/dp/0070428077/ref=sr_1_1?ie=UTF8&qid=1471686003&sr=8-1&keywords=machine+Learning+Tom+Mitchell)_. The table below represents a list of positive and negative examples which we will use to induce a general function. This will be our training DataSet \\\\(D\\\\). \n\n\n| Outlook | Temperature | Humidity | Wind | Play Tennis |\n| ---------| ----------- | ----------- | ----------- | ----------- |\n| Sunny | Hot | High | Weak | False | \n| Sunny | Hot | High | Strong | False |\n| Overcast | Hot | High | Weak | True |\n| Rain | Mild | High | Weak | True |\n| Rain | Cool | Normal | Weak | True |\n| Rain | Cool | Normal | Strong | False |\n| Overcast | Cool | Normal | Strong | True |\n| Sunny | Mild | High | Weak | False |\n| Sunny | Cool | Normal | Weak | True |\n| Rain | Mild | Normal | Weak | True |\n| Sunny | Mild | Normal | Strong | True |\n| Overcast | Mild | High | Strong | True |\n| Overcast | Hot | Normal | Weak | True |\n| Rain | Mild | High | Strong | False |\n\nThe task here is to learn the _Play Tennis_ concept from the attributes: Outlook, Temperature, Humidity and Wind. Each row in the table represents a hypothesis. We will represent this in Kotlin using the `DataPoint` class and use the [Delegated Properties](http://kotlinlang.org/docs/reference/delegated-properties.html) **map** feature. \n\n```kotlin\ndata class DataPoint(val map: Map, val result: Boolean? = null){\n val outlook:String by map\n val temperature: String by map\n val humidity: String by map\n val wind: String by map\n}\n```\n\nThe **Delegated Property map** feature (`by map`) allows us to store properties in a map whilst still allowing accessing them as properties. In the ID3 algorithm we will be using the map to train the algorithm whilst an end user can use the properties directly. Our training DataSet \\\\(D\\\\) can be represented as follows: \n\n```kotlin\nval D = listOf(\n DataPoint(mapOf(\"outlook\" to \"Sunny\", \"temperature\" to \"Hot\", \"humidity\" to \"High\", \"wind\" to \"Weak\"), false),\n DataPoint(mapOf(\"outlook\" to \"Sunny\", \"temperature\" to \"Hot\", \"humidity\" to \"High\", \"wind\" to \"Strong\"), false),\n DataPoint(mapOf(\"outlook\" to \"Overcast\", \"temperature\" to \"Hot\", \"humidity\" to \"High\", \"wind\" to \"Weak\"), true),\n DataPoint(mapOf(\"outlook\" to \"Rain\", \"temperature\" to \"Mild\", \"humidity\" to \"High\", \"wind\" to \"Weak\"), true),\n DataPoint(mapOf(\"outlook\" to \"Rain\", \"temperature\" to \"Cool\", \"humidity\" to \"Normal\", \"wind\" to \"Weak\"), true),\n DataPoint(mapOf(\"outlook\" to \"Rain\", \"temperature\" to \"Cool\", \"humidity\" to \"Normal\", \"wind\" to \"Strong\"), false),\n DataPoint(mapOf(\"outlook\" to \"Overcast\", \"temperature\" to \"Cool\", \"humidity\" to \"Normal\", \"wind\" to \"Strong\"), true),\n DataPoint(mapOf(\"outlook\" to \"Sunny\", \"temperature\" to \"Mild\", \"humidity\" to \"High\", \"wind\" to \"Weak\"), false),\n DataPoint(mapOf(\"outlook\" to \"Sunny\", \"temperature\" to \"Cool\", \"humidity\" to \"Normal\", \"wind\" to \"Weak\"), true),\n DataPoint(mapOf(\"outlook\" to \"Rain\", \"temperature\" to \"Mild\", \"humidity\" to \"Normal\", \"wind\" to \"Weak\"), true),\n DataPoint(mapOf(\"outlook\" to \"Sunny\", \"temperature\" to \"Mild\", \"humidity\" to \"Normal\", \"wind\" to \"Strong\"), true),\n DataPoint(mapOf(\"outlook\" to \"Overcast\", \"temperature\" to \"Mild\", \"humidity\" to \"High\", \"wind\" to \"Strong\"), true),\n DataPoint(mapOf(\"outlook\" to \"Overcast\", \"temperature\" to \"Hot\", \"humidity\" to \"Normal\", \"wind\" to \"Weak\"), true),\n DataPoint(mapOf(\"outlook\" to \"Rain\", \"temperature\" to \"Mild\", \"humidity\" to \"High\", \"wind\" to \"Strong\"), false)\n)\n```\n\n# Decision Trees Representation \nHaving represented our DataSet we will now focus on how to represent the Decision Tree built by using the ID3 algorithm. This algorithm is but one in the family of Decision Tree Learning Algorithms; a family of algorithms which are great at approximating discrete-valued target functions. The output of the ID3 algorithm is a decision tree which can be represented visually as follows: \n \n![](https://cloudmark.github.io/images/kotlin/ID3.png)\n\nIn order to classify (predict) a new instance, we will start off at the root of the tree, test the attribute specified and then move down the tree branch corresponding to the value of the attribute. This process is repeated until a leaf node is reached. \n\nLet us follow with the example:\n\n> **Outlook** = Sunny, **Temperature** = Hot, **Humidity** = High, **Wind** = Strong \n\nWe will start off at the root of the tree which contains the attribute **Outlook** and move to the left subtree (since the value is _Sunny_). The remaining attributes which could be tested are: \n\n> **Temperature** = Hot, **Humidity** = High, **Wind** = Strong \n\nThe root of the left subtree requires us to check the **Humidity** attribute. Since the value of the attribute is _High_ we will move to the left subtree to find the leaf node containing the result **No**. Hence we can infer that this is not a good day to play tennis (but a great time to read this article! :bowtie:). \n\nIn order to represent the following Tree in Kotlin we will make use of the [Sealed Classes](https://kotlinlang.org/docs/reference/classes.html). From their documentation: \n\n> Sealed classes are used for representing restricted class hierarchies, when a value can have one of the types from a limited set, but cannot have any other type. They are, in a sense, an extension of enum classes: the set of values for an enum type is also restricted, but each enum constant exists only as a single instance, whereas a subclass of a sealed class can have multiple instances which can contain state.\n\n```kotlin\nsealed class Tree {\n class Node(val key: String, val children: Map?) : Tree()\n class Leaf(val result: Boolean) : Tree()\n}\n```\n\nThe tree above would be represented as follows: \n\n```kotlin\n Tree.Node(\"Outlook\", mapOf(\n Pair(\"Sunny\", Tree.Node(\"Humidity\", mapOf(\n Pair(\"High\", Tree.Leaf(false)),\n Pair(\"Normal\", Tree.Leaf(true))\n ))),\n Pair(\"Overcast\", Tree.Leaf(true)),\n Pair(\"Rain\", Tree.Node(\"Wind\", mapOf(\n Pair(\"Strong\", Tree.Leaf(false)),\n Pair(\"Weak\", Tree.Leaf(true))\n\n )))\n ))\n```\n\nNote that we could have also represented this as a disjunction of conjunctions. If you are interested you can try it out - depth traversal algorithm comes to mind). \n\n$$\n\\begin{eqnarray} \n(Outlook = Sunny \\wedge Humidity = Normal) \\vee \\nonumber \\newline\n(Outlook = Overcast) \\vee \\nonumber \\newline \n(Outlook = Rain \\wedge Wind = Weak)\n\\end{eqnarray} \n$$\n\n# Classifying New Exemplars. \n\nThe advantage of using a sealed class is that it will make the implementation of the `classify` function more succinct. When paired with the [When Expression](https://kotlinlang.org/docs/reference/control-flow.html#when-expression) feature, sealed classes give us rudimentary pattern matching capabilities . _It would be great to see proper pattern matching support in the coming Kotlin releases._ The implementation of the `classify` function is as follows: \n\n```kotlin\nclass ID3() {\n companion object {\n fun classify(dataPoint: DataPoint, tree: Tree): Boolean = when (tree) {\n is Tree.Leaf -> tree.result\n is Tree.Node -> {\n val value = dataPoint.map[tree.key]\n val subtree = tree.children?.get(value)!!\n classify(dataPoint, subtree)\n }\n }\n }\n}\n```\n\nNote that we are using the [Companion Object](https://kotlinlang.org/docs/reference/object-declarations.html) feature of Kotlin. If you have never seen Companion objects before you can think of them as `public static` methods on the ID3 class. Another feature which we are using is the [Smart Cast](https://kotlinlang.org/docs/reference/typecasts.html) feature. This feature will automatically type cast a variable after using the `is` checks. In this case after the `is Tree.Leaf` expression evaluates to true, tree will automatically be cast to `Tree.Leaf`. \n\n\n# Building the Tree\nNow that we have represented our decision tree and learnt how to classify new exemplars, let us take on the task of building a tree from the example data. The most important question to ask when building a decision tree is \"Which Attribute Is the Best Classifier?\". What we would like to determine is which attribute is the best attribute to classify items at a certain level in the tree, or better, which item gives us the best _information gain_. \n\n## Entropy\nIn order to determine information gain we start off by looking at entropy which measures the (im)purity of an arbitrary collection of examples. Given a collection of elements \\\\(S\\\\) containing only positive and negative items, entropy is measured by: \n\n\\\\[\nEntropy(S) = -p\\_{\\oplus} log\\_{2} p\\_{\\oplus} - p\\_{\\ominus} log\\_{2}p\\_{\\ominus}\n\\\\]\n\nAn intuitive way in which we can think about entropy is a number (\\\\([0,1]\\\\)) which represents the minimum number of bits of information needed to encode the classification of an arbitrary member of \\\\(S\\\\). If the collection \\\\(S\\\\) does not have any positive or negative examples the entropy will be 0. If I pick an item at random from the collection \\\\(S\\\\) and all items are from the same class then the item I picked must be from that class hence we need 0 bits to encode this information. If the distribution of samples is equal, then the entropy is 1. This means that we need at minimum 1 bit to represent a randomly picked item from \\\\(S\\\\). We could encode a positive sample as 1 and a negative sample as 0. As an example, if we have 9 positive examples and 5 negative examples the entropy would be: \n\n$$\nEntropy([9+, 5-]) = -\\frac{9}{14}log\\_{2}\\Big(\\frac{9}{14}\\Big) -\\frac{5}{14}log\\_{2}\\Big(\\frac{5}{14}\\Big) = 0.940\n$$\n\nWe can extend this formula of Entropy to multiple attributes (rather than just _true_ and _false_) as follows: \n\n$$\nEntropy(S) = \\sum\\_{i=1}^{c} -p\\_{i}log\\_{2}p\\_{i}\n$$\n\nwhere \\\\(p\\_{i}\\\\) is the proportion of \\\\(S\\\\) belonging to class \\\\(i\\\\). \n\nIn Kotlin we can express `entropy` as follows: \n\n```kotlin\nfun entropy(positive: Double, negative: Double, total: Double = positive + negative):Double {\n fun log2(valueA: Double, valueB: Double) = if (valueA == 0.0) 1.0 else Math.log(valueA / (valueA + valueB)) / Math.log(2.0)\n return -(positive / total * log2(positive, negative) + negative / total * log2(negative, positive))\n}\n```\n \n\n# Information Gain \nNow that we have defined Entropy as an (im)purity measure, we can answer the question \"Which Attribute Is The Best Classifier?\". This measure is called _Information Gain_ - you can think of this value as the expected reduction in entropy or the expected number of bits saved if we had to encode the classification using the particular attribute. The Information Gain of an attribute \\\\(A\\\\) is defined as: \n\n$$\nGain(S, A) = Entropy(S) - \\sum\\_{v \\in Values(A)} \\frac{|S\\_{v}|}{|S|}Entropy(S\\_{v})\n$$\n\n\nTo understand what we need to do, lets work out the _Information Gain_ of attribute \\\\(Wind\\\\) for the dataset \\\\(S\\\\) i.e. \\\\(Gain(S, Wind)\\\\). _Note that there are 14 examples in our dataset; 9 positive, 5 negative \\\\([9+ 5-]\\\\). There are 2 values for the attribute Wind: Weak and Strong. Weak has 6 positive examples and 2 negative examples \\\\([6+, 2-]\\\\). Strong has 3 positive examples and 3 negative examples \\\\([3+, 3-]\\\\)_. \n\n$$\\begin{eqnarray} \nGain(S, A) &=& Entropy(S) - \\sum\\_{v \\in \\\\{Weak, Strong\\\\} } \\frac{|S\\_{v}|}{|S|}Entropy(S\\_{v}) \\nonumber \\newline\n&=& Entropy(S) - \\frac{8}{14}Entropy(S\\_{Weak}) - \\frac{6}{14}Entropy(S\\_{Strong}) \\nonumber \\newline\n&=& 0.940 - \\frac{8}{14}0.811 - \\frac{6}{14}1.0 \\nonumber \\newline\n&=& 0.048\n\\end{eqnarray}$$\n\nIn Kotlin the Gain can be implemented as follows: \n\n```kotlin\nfun gain(dataPoints: List, extractor: (DataPoint) -> Pair): Double {\n val (positive, negative) = dataPoints.map { extractor(it) }.partition { it.second }\n val attributes = dataPoints.map { extractor(it) }\n .groupBy { it.first }\n .map {\n val (positiveSv, negativeSv) = it.value.partition { it.second }\n Triple(it.key, positiveSv.size.toDouble(), negativeSv.size.toDouble())\n }\n return (entropy(positive.size.toDouble(), negative.size.toDouble())\n + attributes.map({ -entropy(it.second, it.third, dataPoints.size.toDouble()) }).sum())\n\n}\n```\n\nWe can compute the Gain of the attribute Wind as follows: \n\n```kotlin\ngain(dataPoints, { Pair(it.wind, it.result!!) })\n```\n\nThe `extractor` function defined as \n\n```kotlin\nextractor: (DataPoint) -> Pair\n```\n \nis a function which will be called on the dataset \\\\(S\\\\) to extract the information required - the value of the wind property and the classification result. The `!!` is an indication to Kotlin that we are 100% sure that this property will not be null. \n\n# ID3 Tree\nNow that we have all the pieces of our puzzle ready, we will write the `build` function which will create the ID3 Tree. To understand what is going on, I will use a literate programming approach. Below you will find the listing of the build `function`. \n\n```kotlin\n fun build(dataPoints: List): Tree {\n val (positive, negative) = dataPoints.partition { it.result!! }\n if (positive.size == 0) return Tree.Leaf(false)\n if (negative.size == 0) return Tree.Leaf(true)\n val attributes = dataPoints.map { it.map.keys }.flatMap { it }.distinct()\n if (attributes.size == 1) {\n return if (dataPoints.count { it.result!! } > dataPoints.count { !it.result!! }) Tree.Leaf(true) else Tree.Leaf(false)\n } else {\n val (attribute) = attributes.map { attr ->\n Pair(attr,\n gain(dataPoints, { Pair(it.map[attr].toString(), it.result!!) })\n )\n }.sortedByDescending { it.second }.first()\n \n val remaining = dataPoints.groupBy { it.map[attribute] }\n val filteredRemaining = remaining.entries.map {\n entry ->\n Pair(entry.key, entry.value.map { dataPoint ->\n DataPoint(dataPoint.map.filterKeys { it != attribute }, dataPoint.result)\n })\n }\n \n val children = filteredRemaining.map { Pair(it.first.toString(), build(it.second)) }.toMap();\n return Tree.Node(attribute, children)\n }\n}\n```\n\nSome explanations are due. \n\n\nStarting off, we determine whether the DataSet is made up of all positive or all negative sample points (Entropy 0): \n\n``` kotlin\nval (positive, negative) = dataPoints.partition { it.result!! }\nif (positive.size == 0) return Tree.Leaf(false)\nif (negative.size == 0) return Tree.Leaf(true)\n```\nIt such a case we return a `Tree.Leaf` with the corresponding result. \n \nNext we will check how many attributes there are in the DataSet: \n\n```kotlin\nval attributes = dataPoints.map { it.map.keys }.flatMap { it }.distinct()\n```\n \nIf there is only one attribute, then the most common value of the target attribute is returned. \n\n```kotlin\nif (attributes.size == 1) {\n return if (dataPoints.count { it.result!! } > dataPoints.count { !it.result!! }) \n Tree.Leaf(true) else Tree.Leaf(false)\n}\n```\n\nOtherwise, we will first determine \"Which attribute is the best?\" by working the Information Gain of each attribute and retrieve the one with the highest Information Gain: \n\n```kotlin\nval (attribute) = attributes.map { attr ->\n Pair(attr,\n gain(dataPoints, { Pair(it.map[attr].toString(), it.result!!) })\n )\n}.sortedByDescending { it.second }.first()\n```\n\nFor all the values of the chosen attribute: \n\n```kotlin\nval remaining = dataPoints.groupBy { it.map[attribute] }\n```\n\nwe will add a new subtree below the parent node and select the DataSet subset such that the attribute \\\\(A\\\\) in the parent subset matches the value \\\\(v\\_{i}\\\\). \n\n\n```kotlin\nval filteredRemaining = remaining.entries.map {\n entry ->\n Pair(entry.key, entry.value.map { dataPoint ->\n DataPoint(dataPoint.map.filterKeys { it != attribute }, dataPoint.result)\n })\n}\n```\n\nIn this case the attribute which has the highest Information Gain is the Outlook attribute. Since Outlook has three values we will create three subtrees: one for Sunny, one for Overcast and one for Rain. The Sunny Subtree should filter out all data points whose Overcast attribute value is not Sunny. In this case this subtree will have 5 data points; 2 positive examples and 3 negative examples \\\\([2+,3-]\\\\): \n\n\n| Outlook | Temperature | Humidity | Wind | Play Tennis |\n| ---------| ----------- | ----------- | ----------- | ----------- |\n| Sunny | Hot | High | Weak | False | \n| Sunny | Hot | High | Strong | False |\n| Sunny | Mild | High | Weak | False |\n| Sunny | Cool | Normal | Weak | True |\n| Sunny | Mild | Normal | Strong | True |\n\nFinally we will call the build function recursively on this DataSet subset. \n\n```kotlin\nval children = filteredRemaining.map { Pair(it.first.toString(), build(it.second)) }.toMap();\nreturn Tree.Node(attribute, children)\n```\n\nNote that `it.first` will contain the attribute value (e.g. Sunny) whilst the it.second contains the DataSet subset. \n\n\n# Conclusion\nIn this post we have looked at some of Kotlin's key features and we have used these to build an ID3 decision tree. If you are further interested in learning about Kotlin I'd suggest you have a look at the [reference guide](https://kotlinlang.org/docs/reference/). If you are interested in learn more about Decision Tree Learning consider buying the book linked above. It is an absolute classic! Stay safe and keep hacking!\n\n\n","author":"Mark Galea","date":"2016-08-20","type":"article","categories":["Kotlin"],"features":["mathjax","highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Data Binding in Anko","url":"https://medium.com/lewisrhine/data-binding-in-anko-77cd11408cf9#.ym6ibevib","body":"\n\nEver since Google announced their data binding library there has been a debate in the community whether it is “the best thing since fragments” or “the worst thing since fragments”. (I knew you would see that coming, but I did it anyways)\n\nWhen I first heard about it I was excited. I had been playing with AngularJS a lot at the time and I spent about an hour playing with the two-way data binding. Typing text in an input box and watching text in other places change as you type yelling, “Wheeeee, I love JavaScript!” Then I read more about how Google was implementing data binding and was horrified. Logic... In.... Your... X... M... L... Dun Dun Dun!\n\nIf you couldn’t tell from all those dramatic dots, I am on the “it’s bad” side of the binding argument. You can do some really cool things with it. But I just can’t get past having logic in your XML. In fact thinking about it more, why do anything in XML? It’s ugly, dumb, and I hate it.\n\nAnko is a Kotlin library from Jetbrains that provides a lot of extension functions that make Android development much easier. One part of it leverages Kotlin’s ability to create a custom DSL to allow you to build out your views programmatically in a clean simple way. No XML needed. I have wanted to play with this feature of Anko for a while, besides the little bit I did when Kotlin was still in beta that is. So I thought it would be fun to try to build a simple data binding system we can use inside Anko.\n\nFirst things first, I need a simple app with an Anko Component. I just used the example from Anko’s GitHub with some small name changes.\n\n```kotlin\nclass MainActivityUI : AnkoComponent {\n override fun createView(ui: AnkoContext) = with(ui) {\n verticalLayout {\n val name = editText()\n button(\"Say Hello\") {\n onClick { ctx.toast(\"Hello, ${name.text}!\") }\n }\n }\n }\n}\n```\n\nAnd the Activity looks like this.\n\n```kotlin\nclass MainActivity : AppCompatActivity() {\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n MainActivityUI().setContentView(this)\n }\n}\n```\n\nI’m going to start simple by just trying to bind a string to a TextView. My first thought is to have a wrapper class that holds a property and has a hash map of bind functions that it invokes whenever the property is changed. This is what I came up with.\n\n```kotlin\nclass Binder(initValue: T) {\n private val bound: MutableMap Unit> = HashMap()\n var item: T by Delegates.observable(initValue) { prop, old, new -> if (old != new) bound.values.forEach { it(new) } }\n fun bind(id: Int, binding: (item: T) -> Unit) {\n bound.put(id, binding)\n binding(item)\n }\n\n fun unBind(id: Int) = bound.remove(id)\n}\n```\n\nTo simplify binding the data to views I wrote two extension functions that set the id based on the views. This means any view that has any bindings will need an id.\n\n```kotlin\nfun View.bind(binder: Binder, binding: (item: T) -> Unit) = binder.bind(this.id, binding)\n\nfun View.unBind(binder: Binder) = binder.unBind(this.id)\n```\n\nI can come back to these guys at a later data and make them inline to increase performance but for now, I’m not going to worry about it.\n\nI new up a Binder in the Activity passing it an initial string value.\n\n```kotlin\nprivate val bindText = Binder(\"Oh, Hi Mark.\")\n```\n\nThen I add it as a property in the MainActivityUI constructor, add a TextView and bind a function that sets the text of that TextView. Like I said before, the TextView is going to need an id. There is probably a better way of doing it but I just set it to an Int of one.\n\n```kotlin\nclass MainActivityUI(private val bindText: Binder) : AnkoComponent {\n override fun createView(ui: AnkoContext) = with(ui) {\n verticalLayout {\n textView {\n Id = 1\n bind(bindText) { text = it }\n }\n val name = editText()\n button(\"Say Hello\") {\n onClick { ctx.toast(“ Hello, ${ name.text }!”) }\n }\n }\n }\n}\n```\n\nNow whenever that item inside the Binder class is changed it will call that function and reset the TextView text. Also notice back inside the Binder class because we are using an observable delegate. It can check to see if the new string has the same value as the old one and only change it if is different. This saves the UI from needlessly setting the TextView if there was really no change in the value.\n\nNow I want to be able to test that the data binding is working. In my Activity, I created a function to change the Binders text and map it to the button to simulate a change made from outside the UI.\n\nIn the Activity.\n\n```kotlin\nfun changeData(text: String) {\n bindText.item = text\n}\n```\n\nAnd in the Component.\n\n```kotlin\nbutton(\"Say Hello\") {\n onClick { (ctx as MainActivity).changeData(\"Hello Doggy\") }\n}\n```\n\nSo now any time that string is changed it will automatically update the UI. Yay data binding! Now I want to make sure it can be unbound. First I added a new Binder to hold the state of whether or not to bind the data. Since we now have two Binders, I want to try to play with how a model would work. I want to use a pure data class because the are super nice things like models and I love them deeply.\n\n```kotlin\ndata class Model(val bindText: Binder, val bindOn: Binder)\n```\n\nI updated the Activity and Anko Component to use the model instead of just the string. Then I added a second button that binds to the new Boolean Binder.\n\n```kotlin\nbutton {\n id = 2\n bind(model.bindOn) { bindOn ->\n when (bindOn) {\n true -> text = \"Binding On\"\n false -> text = \"Binding Off\"\n }\n onClick { model.bindOn.item = (bindOn == false) }\n }\n}\n```\n\nNow I added logic telling the TextView to bind and unbind based on bindOn\n\n```kotlin\nbind(model.bindOn) {\n when (it) {\n true -> bind(model.bindText) { text = it }\n false -> unBind(model.bindText)\n }\n}\n```\n\nOk, so I can now bind data to the view and unbind it when need be, even based on the binding of another piece of data like a Boolean. I can use pure data classes to do this without the need to use any annotations and generated classes. I’m pretty happy with it.\n\nNow for some extra fun, I decided to add some two-way data binding. I added a textChangedListener to the editText and change the binders string onTextChanged.\n\n```kotlin\nval editText = editText().apply {\n textChangedListener {\n onTextChanged {\n charSequence, p1, p2, p3 ->\n bindText.item = “$charSequence”\n }\n }\n}\n```\n\nAnd now I can type text in an EditText and watch text in textView change as I type... “Wheeeee, I love Kotlin!”\n\nThis was mostly a proof of concept. I’m sure there are better ways of doing this. I might come back to it and play around some more. If so I’ll be sure to make another.\n\nThe source code is up on my GitHub.\n\nThank you.\n\n","author":"Lewis Rhine","date":"2016-12-01","type":"article","categories":["Kotlin","Anko"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"The power of templating in a DSL","url":"http://jonnyzzz.com/blog/2016/09/16/power-of-dsl/","body":"\n\nWelcome a powerful templating engine that \nis available for every DSL in a general \npurpose language.\n\n\nIntroduction\n============\n\nLet's consider a general purpose language (e.g. Scala, Java, Kotlin)\nand a library (or a DSL API library) which helps to define \nobjects for some domain. \n\nWe use the library in a program to yield a domain objects.\nThis means we are allowed to mix the libraly calls with other \ngeneral language calls features. This forms a templates. \n \nYou may recall a `.php` or `.jsp` condition or loop tags as an example.\n\nFor the DSL case the general purpose \nlanguage turns into a powerfull templage engine. Unlike string \ntemplage engines, this approach allows a semantic aware templating as\nall calls goes to the DSL API library. \n\nSemantic aware templates can be used to enrich \n[The DSL Way](http://jonnyzzz.com/blog/2016/09/02/dsl-building/) approach\ntoo. \n\nLet's consider examples.\n\nA DSL example\n=============\n\nI will be using [IntelliJ IDEA](https://www.jetbrains.com/idea/) as an IDE \nand [Kotlin](https://kotlinlang.org) as \\\\(Target Language \\\\) below. Suppose\nwe have a DSL API library for logger configuration implemented in Kotlin. An\nevaluation of `log4j` function yield a logger configuration \n(e.g. for [Log4j](http://logging.apache.org/log4j/1.2/)).\n\nSay we have the following code to setup\n[loggers](http://jonnyzzz.com/blog/2016/09/09/log4j-dsl/). \n\n```kotlin\nlog4j {\n logger(\"category2warn\") {\n + WARN\n }\n}\n```\n\nThe goal is to configure a number of loggers in the exactly \nsame way. Thanks to Kotlin language features, one is allowed to use a \nloop, e.g.\n\n```kotlin\nlog4j {\n listOf(\"A\", \"B\", \"C\").forEach {\n logger(\"category2warn.$it\") {\n + WARN\n }\n }\n}\n```\n\nThis is a straitforward example of a template engine. There \nis nothing specific to be done to have a template engine at all. A mix \nof languge features and DSL API library calls forms the template engine.\n\nThere are no loops support in the logger configuration itself, \nbut thats to DSL API we are allowed to loop over several categories \nto generate all definitions. \n\nThe following part is now a template:\n\n```kotlin\n logger(\"category2warn.$it\") {\n + WARN\n }\n}\n```\n\nOne may go further and decide to extract the collection of categoring into \na function. So we turn the logger configuration code into the following\n\n```kotlin\nlog4j {\n listAllRootPackages().forEach {\n logger(\"category2warn.$it\") {\n + WARN\n }\n }\n}\n```\n\nHere we assume the `listAllRootPackages()` to return a list of \ncategories. There is no longer necessary to have this \nfunction to return a constant list. Instead, it can be implemented\nas we like it to, e.g. it may scan an application package to collect\nall possible root categories. It may use some resources as the input.\n\nOverall, this is the way to turn a static (and declarative) logger \nconfiguration to a flexible thing. It is now psedo-declarative. Meaning\nthere is another program, that yields a declarative configuration script\nduring a build phase. On that phase all templates are getting substituted.\n\nA next step is to extract the actual category setup code (a template)\n\n```kotlin\nlog4j {\n listAllRootPackages().forEach {\n declareCategory(it)\n }\n}\n```\n\nAt that point we have a shared library, where a category is declared \nin the *right* way and reused. Next we use a function aka template all other \nthe place.\n\n\nClosing\n=======\n\nThe examples above show how a general purpose language can \nbe turned into a powerfull templating engine for any DSL APIs.\n\nIt turns out that a general purpose language features turning \nit to a powerfull template engine for a given DSL. It's up to \na developer to decide which features to use. The only requirement\nis to have a properly designed DSL API, so that such transformations \nwere possible.\n\nThe example below illustrates a side-effect or a benefit of using \n[The DSL Way]({http://jonnyzzz.com/blog/2016/09/02/dsl-building/)\nto extend an IDE **without** writing any IDE specific code.\nIt shows how powerfull an \\\\(Original Launguage\\\\) can be\nform the \\\\(Target Language\\\\) perspective.\n\nYou may take a look to\n[the post](http://jonnyzzz.com/blog/2016/09/09/log4j-dsl/)\nfor more formal DSL description for a logger configurations.\n\n","author":"Eugene Petrenko","date":"2016-09-22","type":"article","categories":["Kotlin","DSL"],"features":["mathjax","highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"FRP + Kotlin","url":"https://drive.google.com/file/d/0BxCm4NRlzb3PWjNNaG1KS0Utckk/view","body":"\n\n![Photo from meetup](http://i.imgur.com/DOlI1Of.jpg)\n\n[Slides](https://drive.google.com/file/d/0BxCm4NRlzb3PWjNNaG1KS0Utckk/view)\n\n","author":"Giorgio Natili","date":"2016-11-25","type":"slides","categories":["Kotlin","FP"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Архитектор Kotlin: «Язык программирования — рабочий инструмент. Если никогда их не менять, можно отстать от жизни»","url":"https://dev.by/lenta/main/arhitektor-kotlin-yazyk-programmirovaniya-rabochiy-instrument","body":"\nВ феврале 2016-го, после шести лет разработки, компания JetBrains выпустила в релиз версию 1.0 статически типизированного языка программирования [Kotlin](https://kotlinlang.org/). Его авторы ставили целью создать язык «более лаконичный и типобезопасный, чем Java, и более простой, чем Scala». О том, что из этого вышло, а также о моде на языки программирования, конкуренции между ними, перспективах и «серебряной пуле» в интервью dev.by рассказал руководитель разработки проекта Kotlin в JetBrains​ **Андрей Бреслав**. \n\n\n![](https://dev.by/ckeditor_assets/pictures/20014/content_breslav.jpg)\n\n# О Kotlin и о конкуренции\n\n**— Первому релизу Kotlin предшествовали шесть лет разработки. Получилось ли у вас то, к чему стремились?**\n\n**—** В разные моменты мы стремились к разным вещам, но большая часть из того, что сейчас мы считаем правильными целями, состоялась. Мы хотели сделать удобный язык для разработчиков с широким кругом задач — получилось. Мы хотели сделать язык, который будет нравиться людям и сделает их жизнь заметно лучше — результатом мы довольны. Цели в процессе менялись: менялись приоритеты, появлялись новые внешние обстоятельства — конкуренты, новые платформы. Например, Android, о котором мы изначально не думали, стал для нас очень интересной и важной платформой, и сейчас мы получаем аудиторию в среде Android-разработчиков. Мы придумали компилироваться в JavaScript — сразу такой мысли не было, а сейчас понятно, что это тоже очень полезное направление.\n\n**— Кстати, о конкурентах. За последние 10-15 лет языков под JVM развелось много, и многие на слуху: Groovy, Gosu, Ceylon. Почему этих разработок так много? Почему не удаётся сконцентрироваться на какой-то одной, особенно в случаях, когда цели схожи?**\n\n— Языков программирования вообще появляется много, и поиск в этом поле бесконечен.\n\n> Создать новый язык — одна из немногих задач системного программирования, относительно несложная, с интересной «математикой». Написать базу данных или операционную систему куда сложнее, поэтому это делают не так часто.\n\nМногие языки возникают, чтобы заполнить новые или пустующие ниши. Например, Gosu изначально создавался для внуренних конфигурационных скриптов, то есть как язык внутри конкретного продукта компании Guidewire, и только потом отделился и стал более самостоятельным. Groovy — одна из первых успешных попыток сделать динамически типизированный язык специально для JVM, и в какой-то момент он стал новым словом в этом направлении.\n\n**— Многие ли идеи конкурентов перекочевали в Kotlin?**\n\n— Мы использовали всё полезное, что нашли у других: цели придумывать всё с нуля не было. Из названных языков по задачам мы пересекаемся с Ceylon, но общий набор требований у нас другой. Большой упор в Kotlin — на взаимодействие с существующим кодом, так называемый interop с Java, а создатели Ceylon от этой идеи отказались. Они запускаются на JVM, но при этом полностью переписывают стандартную библиотеку: вместо классов из JDK используется их собственная SDK. Это сильно меняет дело: подмешать немножечко Ceylon в существующий проект на Java — большая проблема просто потому, что язык создан не для этого, а для того, чтобы на нём с нуля разрабатывать красивые проекты. А Kotlin хорошо подходит для уже существующих проектов.\n\n**— Создание обратной совместимости с Java и стало самой сложной частью проекта?**\n\n— Да, это, пожалуй, принесло больше всего головной боли. По пути мы перебрали четыре основных схемы взаимодействия с библиотеками Java. Первая была очень консервативной: мы считали, что код на Java очень небезопасен, и в Kotlin нужно проверять всё, что можно. Оказалось, что это очень неудобно. Потом мы пытались аннотировать Java-библиотеки, чтобы внести в код на Java дополнительную типовую информацию и её использовать — это решение оказалось слишком хрупким. Закончили мы тем, что создали концепцию платформенных типов, у меня есть [целый доклад о ней](http://medianetwork.oracle.com/video/player/1785452087001) на JVM Language Summit. Модель достаточно сложна и оригинальна, но на практике она работает хорошо.\n\n**— Вернёмся к релизу. Первый фидбек уже собран? Что понравилось пользователям?**\n\n— Разным людям — разные вещи. Очень многим нравится, что программы становятся короткими и понятными, что компилятор ловит ошибки, которые другие компиляторы не поймали бы.\n\n> На Kotlin удаётся и прозрачно использовать существующие библиотеки, и писать хорошие новые — а это значит, что можно добавлять немножко кода на Kotlin в существующий проект и ничего не бояться. Есть и узкоспециализированные вещи: пользователям на Android, например, нравится, что у нас маленькая стандартная библиотека.\n\n# Как и почему возникает мода на языки\n\n**— Появились ли в последние лет 10-15 языки, которые уже стали поворотными для сферы или могут ими стать?**\n\n— Есть такое образное выражение: «Язык превратился в COBOL». Казалось бы, COBOL — старый язык, который должны давно забыть, но в реальности на нём работает ещё очень много систем, особенно в финансовой сфере. Мы наверняка пишем на Java больше новых проектов, чем на COBOL, но при этом я не брался бы утверждать, что мы пишем больше кода на Java в целом :).\n\n> Я к тому, что судьбоносными становятся те языки, которые в какой-то момент были популярны — на них пишут много больших систем, которые потом нужно поддерживать, и от них никуда не денешься.\n\nВ своё время C в этом смысле совершил революцию, Java тоже стала судьбоносным языком. Из более новых языков не смогу назвать ни одного — наверное, прошло недостаточно много времени, чтобы они могли набрать такую популярность. Но в любом случае, очень успешные языки были. На JVM это Scala и Groovy, на которых крупные компании написали уже немало кода. Вне JVM в своё время имел огромный успех Ruby, на нём писали крупные web-проекты; потом случился кризис роста, люди стали отказываться от Ruby, но этот язык так или иначе серьёзно повлиял на восприятие динамических языков программирования.\n\nОчень большое влияние на направление мысли оказывают функциональные языки. С одной стороны, это языки семейства Lisp-Scheme и всё, что рядом с ним. На JVM есть Clojure, который воплощает те же идеи. С другой стороны — Haskell и другие языки семейства ML. Думаю, что хорошо закрепится Swift, поскольку Apple переводит на него разработчиков для своих платформ, а платформа — вещь такая, что с ней не поспоришь. Раз велено писать на Swift под устройства Apple, значит, все будут писать на Swift — а язык очень хороший, поэтому никакого сопротивления я не ожидаю.\n\n**— Как вы считаете, стоит ли гнаться за модой на языки?**\n\n— Есть люди, которые получают удовольствие от того, что пробуют новые языки и технологии — им, безусловно, стоит пробовать. А есть те, у которых нет на это времени — им есть смысл подождать, пока более резвые коллеги разберутся, какой из конкурирующих языков лучше, и уже постфактум выбирать язык для себя.\n\n> В принципе, язык программирования — это только рабочий инструмент. Менять его слишком часто не нужно — не будет полноты овладения инструментом. Но если не менять инструменты совсем, можно отстать от жизни.\n\nЗдесь нужен баланс. Важно правильно выбирать инструмент по задаче. Когда мы меняем сферу деятельности или переходим к работе в другой области, или просто устали от проблем с тем, что используем сейчас, то есть смысл рассмотреть новые инструменты, понять, не сделают ли они нашу работу принципиально лучше.\n\n**— Тот же Ruby, да и Swift тоже, частенько называют «хипстерскими языками». Почему они стали такими модными?**\n\n— Элемент моды возникает там, где пишутся короткие маленькие проекты. Люди начинают новый проект каждые три месяца и могут себе позволить очередной из них написать на Ruby или на новомодной технологии на базе JavaScript. Естественно, этот эффект хайпа недолговечен, как и любая мода. В мире клиентской разработки это видно особенно ярко: фреймворки и системы программирования на JavaScript сменяют одна другую со страшной скоростью. Мы даже испытываем некоторые сложности из-за этого при разработке Kotlin, потому что при компиляции в JavaScript нам нужно поддерживать какие-то популярные технологии, а их каждый день появляется очень много, и за всем очень сложно уследить. Для Swift всё сказанное тоже частично релевантно, но у этого языка принципиально другая судьба: это стандартное решение, которое поставляется вместе с платформой, и его выбирают не из-за моды.\n\n**— Есть ли, по-вашему, критерии, по которым язык может «выстрелить»?**\n\n— Возвращаясь к сказанному, самый надёжный способ «выстрелить» — быть языком, привязанным к платформе. В своё время C широко распространился, потому что он был языком для платформы Unix, которая была популярной и очень удобной. Java тоже в распространялась как платформа, и язык был её частью. То же касается C#: пускай это и не единственный, но основной язык для платформы .NET. Опять же, есть JavaScript, который популярен не потому, что он хороший или плохой, а потому, что это язык для браузера, браузер нужен всем.\n\nДать надежный рецепт «Как сделать язык, который станет популярным», я не могу, но есть и другие понятные причины, по которым языки становятся популярными.\n\nЕсть языки, которые распространяются по идеологическим моделям — например, Haskell или в какой-то степени Python. Но идеология — это скорее способ сформировать комьюнити, а не удержать его. Тот же Python — это просто хороший язык для многих задач. А вот кто победит из нескольких конкурирующих языков, которые не являются частью платформы и не являются идеологической революцией — как Kotlin, например, — решает рынок.\n\n> Попадание во время и потребности пользователей, правильная маркетинговая работа, своевременный отзыв от ярких представителей сообщества — это все очень важно, но на популярность влияет ещё целая куча разных вещей, которые трудно предсказывать.\n\n![](https://dev.by/ckeditor_assets/pictures/20015/content_breslav2.jpg)\n\n# Прилетит ли «серебряная пуля»?\n\n**— В каком направлении сейчас меняются языки программирования?**\n\n— Есть выраженная тенденция включения в мейнстримовые языки возможностей, изначально придуманных в мире функционального программирования. Наибольшую популярность получили функции высших порядков и лямбда-выражения.\n\nЕщё одна популярная вещь, которая пришла из функционального мира — неизменяемые данные. Здесь есть вполне понятная причина: многоядерные процессоры, которые не так давно произвели революцию на рынке аппаратных средств, а вместе с собой принесли много так называемого «конкурентного программирования», когда программа выполняется в нескольких параллельных нитях. Разделяемые между разными потоками изменяемые данные ведут себя плохо, ошибки отслеживать очень сложно, а чтобы этих ошибок не делать, нужно очень многое держать в голове. В функциональных языках программирования мутирующие операции изначально не в чести, и сейчас эта идея неизменяемых данных становится всё популярнее, поскольку пользоваться ими гораздо проще и надёжнее.\n\n**— Чего, на ваш взгляд, современным языкам не хватает? Что в них «ещё не пришло» из того, что уже, казалось бы, должно?**\n\n— Про языки мне сложно ответить: если бы знал, чего не хватает, уже добавил бы! Мне кажется, что основные болезненные места на сегодня связаны, как я отмечал выше, с многопоточностью. А там главная сложность в том, что никто не знает хорошей модели для многопоточного программирования. Сама эта идея — независимые нитки исполнения, имеющие общую память — несколько противоестественная, и порождает тяжкие ухищрения на аппаратном уровне. Процессор, синхронизируя кеши между ядрами, фактически реализует message passing, но мы притворяемся, что этого нет, и на самом деле у нас разделяемая память. Но чтобы как-то совладать с многопоточным программированием, мы стараемся поменьше пользоваться разделяемой памятью, и программно реализуем поверх неё — снова message passing!\n\nТак получилось исторически: новые процессоры эмулируют поведение старых для совместимости, поэтому сменить парадигму радикально очень сложно. И это отражается на программировании, конечно. Если бы железо могло быть гибче, программирование тоже было бы другим, я думаю. Но мы все в этом смысле связаны во многом всё той же совместимостью. Можно сделать всё очень здорово — и процессор и языки, но только программ и библиотек под это все никаких не будет, и пользователи останутся на традиционных платформах...\n\n**— У программистов есть давняя мечта о «серебряной пуле» — одном языке, который удовлетворил бы большинство или даже всех. Возможно ли его появление?**\n\n— Думаю, в обозримое время ни один язык не победит. Есть искусственные ситуации, в которых можно писать только на одном языке: например, в случае с клиентским вебом. Основным языком браузера был и остаётся JavaScript, и не очень понятно, может ли это измениться. А в остальных случаях, когда есть свобода выбора, я не вижу никаких предпосылок к появлению универсальной идеи, которая бы всех примирила. Слишком уж много противоречивых требований.\n\n# Надо ли уметь программировать каждому школьнику\n\n**— Программирование становится всё более популярным. Сложится ли так, что через какое-то время программировать должен будет уметь каждый?**\n\n— Не думаю, что такое должно произойти. У людей есть автоматически не приобретаемые навыки, которые нужны всем. Например, писать на родном языке или считать. А вот зачем всем на свете нужно будет программировать, я себе представить не могу. Непрограммисты иногда пишут программы, но, как правило, этим всё же занимаются профессионалы. Например, инженеры, которые работают с численными моделями и используют специализированные языки программирования для математического моделирования. Или люди, которые пользуются сложными офисными программами — внутри того же Microsoft Office есть язык программирования Visual Basic for Applications, на котором часто пишут достаточно сложные вещи.\n\nЕсли человек по роду деятельности никак не связан с таким набором задач, то зачем ему программировать? Многие считают, что раз компьютеры — передний край прогресса, значит, все должны разбираться в компьютерах. Когда квантовая физика казалась передним краем прогресса, многие думали, что все будут очень «квантово» жить, но на самом деле никто не будет жить более «квантово», чем живёт сейчас, по-моему.\n\n**— Тем не менее, пока число программистов растёт, и количество запросов на программы тоже растёт.**\n\n— И в ближайшее время этот рост никуда не денется хотя бы из-за того, что правительство Китая изменяет экономический курс. Насколько я понимаю, количество программистов в Китае должно резко увеличиться в ближайшие годы, и для мирового рынка программистов это будет весьма заметный рост. Означает ли это, что в других странах количество рабочих мест для программистов замедлит рост или начнёт падать — хороший вопрос.\n\n**— Стоит ли тогда, на ваш взгляд, преподавать программирование в школе?**\n\n— Я сам восемь лет преподавал программирование в физико-математической школе, и мне кажется, что это столь же разумно, как и преподавание математики или физики. Другой вопрос — содержание курса. Как правильно преподавать программирование в школе без специализации или с гуманитарным уклоном, я не знаю, но всё равно считаю, что это может быть полезным. Программирование развивает алгоритмические и аналитические навыки мышления, очень полезные по жизни, даже если человек никогда больше не будет писать программы.\n\n","author":"yankoits","date":"2016-06-09","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"Радио-Т 484","url":"https://radio-t.com/p/2016/02/20/podcast-484/","body":"\n* [Kotlin дорос до версии 1.0](http://thenextweb.com/dd/2016/02/15/kotlin-the-pragmatic-language-for-android-and-jvm-has-reached-its-1-0-release/) - 00:02:45.\n* [В чем его прагматизм](https://dzone.com/articles/kotlin-10-is-now-available) - 00:12:57.\n* Версия 3 iTerm2 - 00:42:04.\n* Странная история борьбы Apple - 00:52:37.\n* GitHub добавил поддержку шаблонов - 01:10:35.\n* Go 1.6 - 01:15:12.\n* Страшный баг угрожает нашим серверам - 01:21:21.\n* Архитектура Stack Overflow на 2016 - 01:26:33.\n* Custom Machine Types - конфигурации по вкусу - 01:31:15.\n* Темы наших слушателей\n\n","author":"Umputun, Bobuk, Gray, Ksenks","date":"2016-02-20","type":"article","categories":["Podcast","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":{"url":"http://cdn.radio-t.com/rt_podcast484.mp3","size":72259834}},{"title":"Беглый взгляд на Async-Await в Android","url":"https://habrahabr.ru/post/314574/","body":"\n\n","author":"Макс Ровкин","date":"2016-11-08","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"How I built my first Kotlin-VertX-Hibernate stack","url":"https://hashnode.com/post/how-i-built-my-first-kotlin-vertx-hibernate-stack-cixhsnv1b002au6539uu6iw7r","body":"\nI've been using Kotlin for close to 6 months now, and have been experimenting with quite a number of frameworks trying to find the combination that will allow me the most flexibility as well as great performance.\n\nSince I've used [Spring Boot](http://start.spring.io/) previously, and ran into a few troubles after trying to do things which the framework didn't support, I steered clear of it. `Spring5`, which supports asynchronous operations, only reached Milestone 1 when I was in the market for a new framework. So, I parked it until it was stable enough for production use.\n\n`DropWizard` looked like a decent option as well, considering its use of `Jersey`, `Jetty`, `Jackson`, and `Metrics`.\n\n`JDBI` + `Liquibase` made for decent choices, to take care of the DB layer, but I needed `Hibernate` for the having to switch between `MySQL`, `SQLServer`, and `PostgreSQL`. Since a lot of my existing logging infrastructure depends on `Log4j`, having to hack around to see how I can replace `Logback`, did not seem like a good use of my time.\n\nI've been sharing articles about `VertX` from time to time, including spectacular benchmarks, but haven't used it myself until now. So, I wanted to see how easy it would be to write a complete system in `Kotlin` + `VertX`, and how complex it would be, compared to the other alternatives I've listed above.\n\nMaybe you can be the judge of the ease of the aforementioned setup. Let's start with a basic maven `pom.xml` in the root directory ...\n\n```xml\n\n\n 4.0.0\n com.hashnode\n demo\n jar\n 1.0.0\n Kotlin Vertx Hibernate Demo \n \n\n \n \n\n \n \n\n \n\n```\n\nFor Kotlin support, we need the Kotlin Standard lib:\n\n```xml\n\n org.jetbrains.kotlin\n kotlin-stdlib\n ${kotlin.version}\n\n```\n\n... and the Kotlin Maven plugin:\n\n```xml\n\n \n \n kotlin-maven-plugin\n org.jetbrains.kotlin\n ${kotlin.version}\n \n 1.6\n \n \n \n compile\n process-sources\n \n compile\n \n \n \n test-compile\n process-test-sources\n \n test-compile\n \n \n \n \n \n\n```\n\nWe would be be using 1.0.5-2 for this demo:\n\n```xml\n\n 1.0.5-2\n\n```\n\nFor VertX, we need VertX Core, and if we need to open websockets, or enable REST endpoints, we need VertX Web.\n\n```xml\n\n io.vertx\n vertx-core\n ${vertx.version}\n\n\n io.vertx\n vertx-web\n ${vertx.version}\n\n```\n\nWe would be using 3.3.3 for this demo (note that a Kotlin specific version of VertX will be released in early 2017, for now we're using VertX Java inside Kotlin)\n\n```xml\n\n 3.3.3\n\n```\n\nAnd that's most of the XML boilerplate - you can always switch to `gradle` if you prefer to get away from the `maven` boilerplate.\n\nNow in your `src/main/java` directory (you can also use `src/main/kotlin` if you prefer, but that would require us to configure the Maven Kotlin plugin, to look for source files in that directory), create a `HashnodeDemo.kt` file and add the following code to the file:\n\n```kotlin\nimport io.vertx.core.AbstractVerticle\nimport io.vertx.core.Vertx\nimport io.vertx.core.logging.LoggerFactory\nimport io.vertx.ext.web.Router\nimport java.io.IOException\n\nobject HashnodeDemo : AbstractVerticle() {\n\n // initiate logging system\n private val log = LoggerFactory.getLogger(HashnodeDemo.javaClass)\n\n @JvmStatic\n @Throws(IOException::class)\n fun main(args: Array) {\n\n // setup verx\n val vertx = Vertx.vertx()\n val router = Router.router(vertx)\n\n router.get(\"/\").handler { it.response().end(\" Hello World :-) \") }\n\n // start vertx\n vertx.createHttpServer().requestHandler { router.accept(it) }.listen(9090)\n\n }\n}\n```\n\nNow if you run this class from your IDE (I'm using IntelliJ, so for me it's `right-click` and `Run HashnodeDemo`), and open your browser at `localhost:9090`, you should see `Hello World :-)` in your browser.\n\nSo, with a single `pom.xml` file, and a single Kotlin `object` we've got a web server that can respond to `GET` requests. Nothing fancy yet, but as you would see further on, VertX mostly gets out of your way allowing you almost full control of the response going back.\n\nHandling WebSockets can also be done with extra minimal code, but I'll cover that in more detail in a future post:\n\n```kotlin\nvertx.createHttpServer().websocketHandler { ws ->\n log.info(\"WebSocket Connected\")\n ws.handler {\n // print content of request to logs\n log.info(it.toString())\n // write data back to browser\n ws.writeFinalTextFrame(\"Hello World\")\n }\n}.requestHandler { router.accept(it) }.listen(port)\n```\n\nCORS support can also be added with an extra couple of lines (this route should be added before any `GET`, `POST`, etc... routes). To allow cross-domain cookies, use `allowCredentials`\n\n```kotlin\n// handle CORS\nrouter.route().handler(\n CorsHandler.create(origin)\n .allowCredentials(true)\n .allowedMethod(HttpMethod.GET)\n .allowedMethod(HttpMethod.POST)\n .allowedMethod(HttpMethod.OPTIONS)\n .allowedHeader(\"X-PINGARUNER\")\n .allowedHeader(\"Content-Type\"))\n```\n\nVertX, just like NodeJS, uses an event-loop, and at no point should the event-loop be blocked. If you do block it, expect lots of warnings in your logs, and a poor performance. Fortunately, VertX gives you a mechanism out of the box that will allow you to handle blocking requests with ease.\n\nTo demonstrate, let's add some ASCII art that will displayed when the application starts. In `src/main/resources`, create `ascii.txt` and add some ASCII art to it:\n\n```\n _ _ _ _ _____ \n | | | | | | | | | __ \\ \n | |__| | __ _ ___| |__ _ __ ___ __| | ___ | | | | ___ _ __ ___ ___ \n | __ |/ _` / __| '_ \\| '_ \\ / _ \\ / _` |/ _ \\ | | | |/ _ \\ '_ ` _ \\ / _ \\\n | | | | (_| \\__ \\ | | | | | | (_) | (_| | __/ | |__| | __/ | | | | | (_) |\n |_| |_|\\__,_|___/_| |_|_| |_|\\___/ \\__,_|\\___| |_____/ \\___|_| |_| |_|\\___/\n\n Starting Hashnode Demo 1.0.0 ...\n\nJust before `//start vertx`, add the following block of code:\n\n // show ascii art\n vertx.executeBlocking({\n it.complete(InputStreamReader(javaClass.getResourceAsStream(\"/ascii.txt\")).readText())\n }, {\n log.info(it?.result())\n })\n```\n\nDuring startup, the blocking call to the file-system would run in a worker pool while the rest of VertX continues to run asynchronously — best of both worlds; handling an asynchronous request, while still being able to make use of blocking calls in the background...\n\nNow before you follow this tutorial and add `Hibernate` to your project, consider the vast array of options available. `Hibernate`, in my opinion, is the most feature-complete ORM out there, but that also makes it the heaviest ORM available. Other options include:\n\n* [JDBI](http://jdbi.org/) looks decent if you just want to write normal SQL queries, by hand, and need help in binding params and results\n* [VertX JDBC](http://vertx.io/docs/vertx-jdbc-client/java/) is very bare-bone, and will probably require lots of work on your side, depending on what you are looking for\n* [ReQuery](https://github.com/requery/requery) comes bundled with RxJava out of the box, and feels almost like `Hibernate`, but it's much more lightweight\n* [Falkon](https://github.com/jayrave/falkon) is another option if you like the DSL style\n* [JOOQ](http://www.jooq.org/) also comes highly recommended.\n* Kotlin [Kwery](https://github.com/andrewoma/kwery), I've had a look at it, but haven't used it yet.\n\nTo get started with `Hibernate`, let's add some more dependencies in our `pom.xml`:\n\n```xml\n\n\n org.hibernate\n hibernate-core\n ${hibernate.version}\n\n\n org.hibernate\n hibernate-entitymanager\n ${hibernate.version}\n \n \n cglib\n cglib\n \n \n dom4j\n dom4j\n \n \n\n\n org.hibernate\n hibernate-validator\n ${hibernate.version}\n\n```\n\nLet's use MySQL for this demo:\n\n```xml\n\n mysql\n mysql-connector-java\n ${mysql.version}\n\n```\n\nAnd while we're at it, let's add a connection pool as well, to reduce latency:\n\n```xml\n\n org.hibernate\n hibernate-c3p0\n ${hibernate.version}\n\n```\n\nWe would be using the latest versions of the MySQL driver, and Hibernate:\n\n```xml\n \n 6.0.5\n 5.2.4.Final\n\n```\n\nWe would also need to setup the `persistence.xml` file at `src/main/resources/META-INF/persistence.xml`\n\n```xml\n\n\n \n Persistence XML\n org.hibernate.jpa.HibernatePersistenceProvider\n false\n \n\n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n\n \n \n\n```\n\nThe `hibernate.dialect` sets the flavour of SQL you are running. We would be using `MySQL` with `InnoDB` for this demo. `hibernate.hbm2ddl.auto` can be set to `validate`, to validate the database against the current database model; `update` will update your database based on your model; whereas `create-drop` will recreate your database effectively every time your restart.\n\nSet `hibernate.hbm2ddl.auto` to `validate` when going to production, otherwise you might just drop / corrupt your production database.\n\nThe `JDBC Config` is simply where you configure the location of your database, username, and password.\n\nThe `Connection Pool` section allows us to setup a connection pool, in this example we set it to use only 5 connections at maximum. If your application is the only application connecting to the database, you can set that close to the maximum number of connections your database can handle. Just remember that those connections will be kept open as long as the application is running.\n\nLet's create a few `Hibernate` models — first, let's create a base model so that we don't have to re-declare all the basic fields in all the models we create. Create a new directory `src/main/java/com/hashnode/demo/model`\n\nNow, let's create the base model in `StandardEntity.kt`:\n\n```kotlin\npackage com.hashnode.demo.model\n\nimport java.util.*\nimport javax.persistence.*\n\n@MappedSuperclass\nopen class StandardEntity {\n\n @Id\n @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)\n @Column(name = \"id\")\n var id: Int? = null\n\n @Version\n @Column(name = \"version\")\n private var version: Int = 0\n\n @Temporal(TemporalType.TIMESTAMP)\n var created: Date = Date()\n\n @Temporal(TemporalType.TIMESTAMP)\n var modified: Date = Date()\n\n @PreUpdate\n protected fun onUpdate() {\n this.modified = Date()\n }\n\n}\n```\n\nNotice the `@MappedSuperclass`. If you want to extend a base model in `Hibernate`, that base model should be annotated with `@MappedSuperclass`, otherwise extending the base model won't work.\n\nLet's create another entity in `Company.kt`\n\n```kotlin\npackage com.hashnode.demo.model\n\nimport com.hashnode.demo.model.StandardEntity\nimport javax.persistence.Column\nimport javax.persistence.Entity\nimport javax.persistence.EntityManager\nimport javax.persistence.Table\n\n@Entity\n@Table(name = \"Companies\") \nclass Company(\n\n @Column(unique = true)\n var name: String = \"\"\n\n) : StandardEntity() {\n\n fun getCompanyByName(em: EntityManager, name: String): Company {\n val query = em.createQuery(\"SELECT o FROM Company AS o WHERE o.name=:name\", Company::class.java)\n query.setParameter(\"name\", name)\n return query.singleResult\n }\n\n}\n```\n\nNext we bootstrap `Hibernate` in our main class, `HashnodeDemo.kt`. First let's add a `lateinit` variable, just after we initiate logging:\n\n```kotlin\nobject HashnodeDemo : AbstractVerticle() {\n\n // initiate logging system\n private val log = LoggerFactory.getLogger(HashnodeDemo.javaClass)\n lateinit var emf: EntityManagerFactory\n```\n\n`lateinit` indicates that we don't want the variable to be `null`, but we don't want to initialise it immediately either.\n\nJust before we display the ASCII art, we instantiate `emf`.\n\n```kotlin\n// setup hibernate\nemf = Persistence.createEntityManagerFactory(\"default\", hibernate)\n```\n\nThis setup would give you a very quick startup time, but `Hibernate` will only startup after the first query has been fired, meaning your first user will get a very slow response. To fix that, we make a dummy query which would force `Hibernate` to start in the background.\n\n```kotlin\nvertx.executeBlocking({\n it.complete(emf.createEntityManager().createNativeQuery(\"SELECT 'Hibernate Ready!'\").singleResult)\n}, {\n log.info(it?.result())\n})\n```\n\nSince we're using the entity manager, all queries would require an entity manager, whether you do a query inside, or outside of a transaction. Let's create a few helper functions to make that easier.\n\nCreate another package where you can place your utils, and add a `Transaction.kt` file to it. Add the following code to your `Transaction.kt` file:\n\n```kotlin\npackage com.hashnode.demo.util\n\nimport io.vertx.core.logging.LoggerFactory\nimport javax.persistence.EntityManager\n\nval log = LoggerFactory.getLogger(AtomApi.javaClass)\n\n/**\n * Inline wrapper function used for doing transactions\n */\ninline fun transaction(f: (em: EntityManager) -> Unit) {\n val em = AtomApi.emf.createEntityManager()\n try {\n em.transaction.begin()\n f(em)\n em.transaction.commit()\n } catch (e: Exception){\n log.error(e.message, e)\n em.transaction.rollback()\n } finally {\n em.close()\n }\n}\n\n/**\n * Inline wrapper function to give access to the entity manager in codeblock\n */\ninline fun notransaction(f: (em: EntityManager) -> Unit){\n val em = AtomApi.emf.createEntityManager()\n try {\n f(em)\n } catch (e: Exception){\n log.error(e.message, e)\n } finally {\n em.close()\n }\n}\n```\n\nNow whenever you need to run a bunch of queries that should be transactional, use a transaction block:\n\n```kotlin\ntransaction { em ->\n val query = em.createQuery(\"SELECT o FROM Company AS o WHERE o.id=:id\", Company::class.java)\n query.setParameter(\"id\", company.id)\n val company = query.singleResult\n\n company.name = \"new company name\"\n em.merge(company);\n}\n```\n\nAnd for non-transactional queries, simply use the `notransaction` block in the same way.\n\n```kotlin\nnotransaction { em ->\n val query = em.createQuery(\"SELECT o FROM Company AS o WHERE o.id=:id\", Company::class.java)\n query.setParameter(\"id\", company.id)\n val company = query.singleResult\n println(company.name) \n}\n```\n\nAny new entities, which you want to create (or update), should always be in a `transaction` block. This can be done in a one-liner (remember, if you don't specify the lambda-variable in Kotlin, it defaults to `it`)\n\n```kotlin\ntransaction { it.persist(Company(name = \"another company\")) }\n```\n\nRemember that `JDBC` is blocking, so any `Hibernate` queries should be run using `vertx.executeBlocking`. This is typically how you would structure it, either pass in the `ServerWebSocket`; or the `Route`, if you're using the REST (`GET`, `POST`, etc...) methods. Execute the query inside the `executeBlocking` section, and write the result back in the second lambda.\n\n```kotlin\nfun listCompanies(vertx: Vertx, ws: ServerWebSocket, session: Session, data: String) {\nvertx.executeBlocking>({\n notransaction { em ->\n val query = em.createQuery(\"SELECT o FROM Company\", Company::class.java) \n it.complete(query.resultList)\n }\n }, {\n if (it.succeeded()) {\n ws.writeFinalTextFrame(Event(\"listCompanies\", it.result()).toString())\n }\n })\n}\n```\n\nHow you structure your files, is completely up to you. You could even use extension methods to cut down on the boilerplate, but you do have the option to structure things according to how they suit you the best.\n\nAs I've shown, `Kotlin` to `VertX`, works like a well-fitting glove to a hand. Adding an ORM-layer is straight-forward as well. I've also demonstrated the addition of `Hibernate`, which in my case was the right choice for the stack that I work on. If you don't need to jump between databases, and prefer something more lightweight, be sure to check out the other options I have mentioned above.\n\nIf you have any questions, feel free to post them here, and I'll respond when time allows.\n\n","author":"Jan Vladimir Mostert","date":"2017-01-03","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin & Android: A Brass Tacks Experiment, Part 2.","url":"https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-2-c67661cfdf5f#.x698dgmuz","body":"\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*UN-S8ELMC2kpHf4tJKfbLQ.png)\n_Disclaimer: I am a Google employee, but the views expressed in this article are not those of my employer._\n\n### Kotlin & Android: A Brass Tacks Experiment, Part 2\n\nThis is part 2 of a series exploring what the Kotlin® language can uniquely offer Android developers. [Last time](https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-1-3e5028491bcc) there was some detail on how to get Kotlin support added to an Android project. Now we’ll actually dive into code and see how some Kotlin language features can be used to do nifty things in an Android project.\n\nWhen I first encountered Kotlin and pored over the list of language features, one thing in particular stood out to me. Kotlin has a feature called [type-safe builders](https://kotlinlang.org/docs/reference/type-safe-builders.html) that lets you express object creation in a style that looks declarative. It allows a syntax that looks a lot like Gradle build files. But where Gradle and Groovy are dynamically typed, Kotlin is statically typed, so the compiler will let you know if you’re assigning values to properties that don’t make sense.\n\nThe typical examples of type-safe builders show how it’s possible to build nested data structures, like XML documents. When I think Android and XML, layouts and views quickly come to mind. If Kotlin is good at building up stuff like XML programmatically, perhaps it would do well with view hierarchies. So, that’s where I started. I figured I would try to create a sort of shorthand for building view hierarchies programmatically, which is code-intensive if you’re doing it in the Java® language.\n\nImportant note: I will be referring to _lambdas_ frequently going forward. Before continuing, be sure you understand what that means in the context of computer programming, even if not specifically for Kotlin. In short, it’s a way of expressing an anonymous function that you would pass inline to another function or assign to a variable.\n\nThe core feature of Kotlin that makes type-safe builders possible is called [_lambda with receiver_](https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver). Let’s get straight into an example that’s actually useful. Kotlin allows you to define functions outside of classes, and that’s all I’m doing here. Also note that the names of variables come before their types, which is the opposite of the Java language.\n\n```kotlin\nimport android.content.Context\nimport java.lang.reflect.Constructor\n\ninline fun \n v(context: Context, init: TV.() -> Unit) : TV {\n val constr = TV::class.java.getConstructor(Context::class.java)\n val view = constr.newInstance(context)\n view.init()\n return view\n}\n```\n\nThe above function is named v for brevity as I’ll use it a lot here and in future posts, and you can call it like this:\n\n```kotlin\nimport android.view.ViewGroup.LayoutParams\nimport android.view.ViewGroup.LayoutParams.WRAP_CONTENT\nimport android.widget.TextView\n\nval view = v(context) {\n layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)\n text = \"Hello\"\n}\n```\n\nThat’s equivalent to inflating an XML layout that looks like this:\n\n```xml\n\n```\n\nNeat! Now, if this is your first time seeing Kotlin, there’s a lot to translate into English! Here’s a few bits of Kotlin syntax to unpack:\n\n> \n\nThe word [reify](http://dictionary.reference.com/browse/reify) means “to make an abstract thing concrete”. As a Kotlin keyword on a [function’s generic type](https://kotlinlang.org/docs/reference/generics.html#generic-functions), this means that you have compile-time access to the JVM Class object specified for the generic type in the body of the function. So this bit of code says that the function v makes use of a “reified” generic type named TV (think “Type of View”) which must be View or a subclass of View. The function must also be declared inline for this to work. The caller then gives TV a specific type in angle brackets when calling the function.\n\n> init: TV.() -> Unit\n\nv takes two parameters, a Context and a lambda named init. init is special because it’s a lambda with receiver type function reference. A lambda with receiver is a block of code that requires an object of a certain type. This required object is referenced by the keyword “this” in the body of the lambda. The type of the receiver object here is the reified generic type TV.\n\nIn our specific case, function v is declaring, “I’m going to create an object of type TV, and I need you to tell me how to initialize it”. So this new TV type object becomes the receiver of the provided lambda, and the lambda is invoked by v with view.init() so it can perform some actions with the view. The “-> Unit” in the syntax is just saying that the lambda returns type Unit, which is like the type void in Java code. In other words, it returns nothing.\n\nTo summarize this lambda with receiver:\n\n* v declares a parameter called init which is a lambda with receiver for type TV.\n* v creates and initializes a TV type object and invokes the lambda on it to initialize it.\n* The lambda sees the TV type object as “this” in its chunk of code.\n\n> TV::class.java\n\nTo reference the reified generic type TV’s implicitly available Class object in the function, you can use the expression TV::class.java. This kind of expression is a very special Kotlin feature for reified generic types that drastically reduces the amount of code you must write in functionally equivalent Java code.\n\nAt this point, I’m going to anticipate a couple more questions you might have about this function:\n\n> “Why does v take two arguments, but appear to be given only one inside the argument parenthesis?”\n\nThis is another unfamiliar syntax to Java programmers. In the Java language, all the arguments to a function always appear inside the call’s parentheses, which can be a lot of added lines if it includes an anonymous callback. But in Kotlin, there is a special syntax when a lambda is the last argument to a function. This syntax allows the lambda to appear in curly braces _immediately following_ the parentheses of the function call. You _could_ put the whole thing inside the parentheses, but most of the time it’s neater this way and keeps the function call parentheses on the same line, so they’re easier to track. Also, this lambda syntax is similarly available when inlining anonymous Java objects that have a single method, such as Runnable.\n\n> “Are ‘layoutParams’ and ‘text’ some sort of variables?”\n\nA syntax feature of a lambda with receiver is that the “this” keyword may be omitted when referencing methods and [properties](https://kotlinlang.org/docs/reference/properties.html) of “this” inside the lambda. But what exactly are layoutParams and text in the call example? These are provided by Kotlin as properties of the receiver type TV (a TextView in our example). Because TextView has methods for setLayoutParams() and setText(), Kotlin recognizes those as JavaBeans-style accessors and creates properties for them that can be accessed as if they were Java class members. So, text = “Hello” here is exactly equivalent to this.setText(“Hello”). Slick! Here’s a screenshot of Android Studio with the Kotlin plugin showing specifically what’s going on during autocomplete:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/0*vDlPyDAn73AbhqQO.)\n_The IDE’s autocomplete suggests which methods are backing Kotlin properties._\n\nAs you can see, the Kotlin plugin is pointing out to us that the property called “text” (among other properties) is derived from the underlying JavaBeans-style getter and setter methods of the TextView type receiver object.\n\n> “What is this Constructor business? Can’t we just say “new TV(context)”?”\n\nSince the compiler doesn’t know exactly what a TV is yet in the method body of v, we can’t instantiate it using new + classname. However, we can use the reified class object (TV::class.java) to locate a Constructor that takes a Context as the single argument. It’s conventional for Android View types to have a constructor with this signature, and we’re depending on it. This Constructor object can be invoked to get a new instance of type TV, with the same effect as the new keyword in Java code. This is a reasonable price to pay for the flexibility of having a single function work for all types of views instead of creating a whole new function for each type of view you want to build. And we can optimize this a bit more later in a future part to this blog series.\n\nThat’s a whole lot of convenience for a few lines of code! If you’re new to Kotlin, you might want to go back and digest this a second time, because some of these concepts can be very foreign to Java programmers. It certainly took me a bit of studying to grok all this new stuff.\n\nThis is just the beginning of my experiment. There’s still many ways this function could be enhanced and made easier to use. For example, it would be great if we could build entire nested view hierarchies in a single expression. So stay tuned for [the next post in this series](https://medium.com/@CodingDoug/kotlin-android-a-brass-tacks-experiment-part-3-84e65d567a37) to see how we can use Kotlin to do that!\n\n","author":"Doug Stevenson","date":"2016-02-01","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Keddit — Part 7: Infinite Scroll: Higher-Order functions & Lambdas","url":"https://medium.com/@juanchosaravia/keddit-part-7-infinite-scroll-higher-order-functions-lambdas-3a11fbd5090e#.cdsuea4kc","body":"\n![](https://d262ilb51hltx0.cloudfront.net/max/2000/1*coKbXMpkG8Fc1NJtM6Jp4w.png)\n\n### Content\n\n* [Introduction: A few words about this](https://medium.com/@juanchosaravia/learn-kotlin-while-developing-an-android-app-introduction-567e21ff9664)\n* [Part 1:](https://medium.com/@juanchosaravia/learn-kotlin-while-developing-an-android-app-part-1-e0f51fc1a8b3) [Configuring Android Studio with Kotlin](https://medium.com/@juanchosaravia/learn-kotlin-while-developing-an-android-app-part-1-e0f51fc1a8b3)\n* [Part 2: MainActivity.kt: Syntax, Null Safety and more...](https://medium.com/@juanchosaravia/learn-kotlin-while-developing-an-android-app-part-2-e53317ffcbe9)\n* [Part 3: NewsFragment.kt: Extension Functions, Android Extensions...](https://medium.com/@juanchosaravia/keddit-part-3-extension-functions-android-extensions-and-more-faa7d232f232)\n* [Part 4: RecyclerView — Delegate Adapters & Data Classes with Kotlin](https://medium.com/@juanchosaravia/keddit-part-4-recyclerview-delegate-adapters-data-classes-with-kotlin-9248f44327f7)\n* [Part 5: Kotlin, RxJava & RxAndroid](https://medium.com/@juanchosaravia/keddit-part-5-kotlin-rxjava-rxandroid-105f95bfcd22)\n* [Part 6: API — Retrofit & Kotlin](https://medium.com/@juanchosaravia/keddit-part-6-api-retrofit-kotlin-d309074af0)\n* [Part 7: Infinite Scroll: Higher-Order functions & Lambdas](https://medium.com/@juanchosaravia/keddit-part-7-infinite-scroll-higher-order-functions-lambdas-3a11fbd5090e)\n* Part 8: Orientation Change (Parcelables & Data Classes)\n* Part 9: Unit & Integration Tests\n\n### Part 7: Infinite Scroll: Higher-Order functions & Lambdas\n\nThanks to all the previous stories we have a small Reddit client App that **shows the Top news from Reddit** and what we need now is to allow the user to see not only the first 10 news but the next news that also belongs to this Top Reddit news. That’s why we introduce here the Infinite Scroll.\n\nThe implementation of the infinite scroll was inspired by [this article](http://msobhy.me/2015/09/05/infinite_scrolling_recyclerview/) and the author is [Mohamed Sobhy](https://twitter.com/@mSobhy90). I made just a few changes to provide an example of Higher-Order functions and passing a lambda expression as parameter.\n\n### Higher-Order Functions\n\n> A higher-order function is a function that takes functions as parameters, or returns a function.\n\nWell, lets see how Kotlin allows you to pass functions as parameter or return it with some examples.\n\nThis function “**logExecution**” allows you to pass a function as parameter and log before and after the execution of this function.\n\n```kotlin\nfun logExecution(func: () -> Unit) {\n Log.d(\"tag\", \"before executing func\")\n func()\n Log.d(\"tag\", \"after executing func\")\n}\n```\n\n#### func: ()-> Unit\n\nAs you already know, “**func**” is the name of the parameter and “**() -> Unit**” is the “type” of the parameter, in this case, we are saying that **func** will be a function that **doesn’t receive any parameter and doesn’t return any value** (remember that Unit works like void in Java).\n\nYou can call this function by passing a lambda expression that must not receive or return any value, like in this way:\n\n```kotlin\nlogExecution( { Log.d(\"tag\", \"I'm a function\") } )\n```\n\nbut also Kotlin allows you to remove the parenthesis if there is only one function parameter or if the last parameter is a function:\n\n```kotlin\nlogExecution { Log.d(\"tag\", \"I'm a function\") }\n```\n\nIf we change the **logExecution** signature to receive another parameter and we put the function parameter at the end, we can do this:\n\n```kotlin\n// added tag parameter:\nfun logExecution(tag: String, func: () -> Unit) { ... }\n\n// call in this way:\nlogExecution(\"tag\") { Log.d(\"tag\", \"I'm a function\") }\n```\n\nor:\n\n```kotlin\nlogExecution(\"tag\") {\n Log.d(\"tag\", \"I'm a function\")\n}\n```\n\nAlso you can make the function to receive and return values:\n\n```kotlin\nfun logExecution(func: (String, String) -> Int) {\n val thisIsAnInt = func(\"Hello\", \"World\")\n}\n```\n\nAs you can see Kotlin gives you a lot of power with Higher-Order functions. Also this allows you to remove a lot of Android ceremonies that requires you to initialize things before to execute something or never forget to close a cursor, and much more.\n\n#### Async function example\n\nLets see a practical example. We are going to create a new function that receives a function and execute it in another thread:\n\n```kotlin\nfun runAsync(func: () -> Unit) {\n Handler().post(Runnable { func() })\n}\n```\n\nNow we can execute a function outside of the Main UI Thread easily:\n\n```kotlin\nrunAsync {\n // i.e.: save something in the Database\n}\n```\n\n#### Is Lollipop example\n\nMaybe you want to run some specific code for Lollipop devices and instead of doing the regular if check, you can use this function:\n\n```kotlin\nfun isLollipopOrAbove(func: () -> Unit) {\n if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n func()\n }\n}\n```\n\nand use it in this way:\n\n```kotlin\nisLollipopOrAbove {\n // run lollipop specific code safely\n}\n```\n\n### Infinite Scroll\n\nOk lets see how we can take advantages of this new concept and create our infinite scroll behaviour.\n\nThe RecyclerView allows you to set a Scroll Listener so I created this [InfiniteScrollListener](https://github.com/juanchosaravia/KedditBySteps/blob/master/app/src/main/java/com/droidcba/kedditbysteps/commons/InfiniteScrollListener.kt) and I defined the signature of this class in this way:\n\n```kotlin\nclass InfiniteScrollListener(\n val func: () -> Unit,\n val layoutManager: LinearLayoutManager)\n : RecyclerView.OnScrollListener() {...}\n```\n\nWhat we are doing here is to receive a function parameter that will be invoked every time we get to the end of the RecyclerView ([see line 36 for more details](https://github.com/juanchosaravia/KedditBySteps/blob/master/app/src/main/java/com/droidcba/kedditbysteps/commons/InfiniteScrollListener.kt#L36)). In fact, it will be called before to reach the end of the list, you can set a threshold that will make our function to be invoked a few items before and in this way you provide a better experience and not making the user to see all the time the loader that more news were requested.\n\nThe function that we are going to pass as parameter is a function that request more news and update the NewsAdapter with the new received news:\n\n```kotlin\nnews_list.addOnScrollListener(\n InfiniteScrollListener({ requestNews() }, linearLayout)\n)\n```\n\n**requestNews()** is a function that we already have in our code, I update it to use pagination and request the next available news from Reddit.\n\nAs you may notice, I’m not passing requestNews() **but inside a lambda expression**. This is because the compiler will not take it as a function parameter but as a function that needs to be executed and use the return type of this function as the value that we are passing to the InfiniteScrollListener. As the return type of requestNews is “Unit”, it doesn’t match the InfiniteScrollListener parameter expected which is “()->Unit”, so this code will not compile except if you put this into the lambda expression that match perfectly the required parameter.\n\n#### Commit:\n\nHere you have all the code added to include Infinite Scroll behaviour:\n\n[https://github.com/juanchosaravia/KedditBySteps/commit/3bedf81ad25aecf24aacc224c6591072eccf5b73](https://github.com/juanchosaravia/KedditBySteps/commit/3bedf81ad25aecf24aacc224c6591072eccf5b73)\n\n### Conclusion\n\nWe are now able to scroll and see more news from Reddit Top list. All the details can be reviewed in the previous commit.\n\nHigher-Order functions is an incredible feature and hope it is more clear now with these examples. I invite you to post other examples if you feel inspired.\n\nSee you in the next story!\n\n**Twitter**: [https://twitter.com/juanchosaravia](https://twitter.com/juanchosaravia)\n\n","author":"Juan Ignacio Saravia","date":"2016-04-09","type":"article","categories":["Android","Kotlin","Keddit"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin vs Java: Compilation speed","url":"https://medium.com/keepsafe-engineering/kotlin-vs-java-compilation-speed-e6c174b39b5d#.kls4hgglt","body":"\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*J-1MC3QGbIuwq4tb-yr-iA.png)\n\n_[XKCD, Randall Munroe](https://xkcd.com/303/) // [CC BY-NC 2.5](https://creativecommons.org/licenses/by-nc/2.5/)_\n\n# Kotlin vs Java: Compilation speed\n\n_If you convert an app from Java to Kotlin, will it take longer to compile?_\n\n_This is part 3 in a series of articles on Kotlin._ [_Part 1 discussed_](https://medium.com/keepsafe-engineering/lessons-from-converting-an-app-to-100-kotlin-68984a05dcb6) _converting an Android app from Java to Kotlin, and_[ _part 2 contains_](https://medium.com/keepsafe-engineering/kotlin-the-good-the-bad-and-the-ugly-bf5f09b87e6f) _my thoughts on the Kotlin language._\n\nIn an earlier article, [I discussed converting an Android app from Java to 100% Kotlin](https://medium.com/keepsafe-engineering/lessons-from-converting-an-app-to-100-kotlin-68984a05dcb6). The Kotlin codebase was smaller and more maintainable than it’s Java predecessor, and so I concluded that the transition was worth it. But some people don't want to try out Kotlin because they are worried that it might not compile as quickly as Java. That’s definitely a valid concern; no one wants to spend the time to convert their codebase if it will result in long build times. So let’s take a look at the difference in compile times of the [App Lock app](https://play.google.com/store/apps/details?id=com.getkeepsafe.applock), before and after I converted it to Kotlin. I won’t be trying to compare the speed of a single line of Kotlin versus a single line of Java; instead, I’ll try to answer the question of whether converting a codebase from Java to Kotlin will affect its overall build time.\n\n### How I tested build times\n\nI wrote shell scripts to run Gradle builds repeatedly in a variety of scenarios. All tests are performed 10 times consecutively. The project is cleaned before each scenario, and for scenarios that use the [Gradle daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html), the daemon is stopped once before benchmarking that scenario.\n\nAll benchmarks in this article were performed on an Intel Core i7–6700 running at 3.4 GHz, with 32GiB of DDR4 memory and a Samsung 850 Pro SSD. The source code was built with Gradle 2.14.1.\n\n### Tests\n\nI wanted to run benchmarks in several common usage scenarios: clean builds with and without the Gradle daemon, incremental builds with no file changes, and incremental builds with a changed file.\n\nBefore the transition, App Lock’s Java codebase was 5,491 methods and 12,371 lines of code. After the rewrite, those numbers dropped down to was 4,987 methods and 8,564 lines of Kotlin code. No major architectural changes occurred during the rewrite, so testing the compile times before and after the rewrite should give a pretty good idea about the difference in build times between Java and Kotlin.\n\n#### Clean builds with no Gradle daemon\n\nThis is the worst-case scenario for build times in both languages: running a clean build from a cold start. For this test, I disabled the Gradle daemon.\n\nHere’s how long each of ten builds took:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*VM3VcA0f0XdjnTWDjOqgQg.png)\n\n_Ten consecutive clean builds without the Gradle daemon_\n\nThe result in this scenario is that Java build times have an average of 15.5 seconds, while Kotlin averages 18.5 seconds: an increase of 17%. Kotlin is not off to a great start, but this isn’t how most people will compile their code.\n\n> For clean builds with no Gradle daemon, Java compiles 17% faster than Kotlin.\n\nIt’s much more common to repeatedly compile the same codebase as you make changes to it. That’s the kind of scenario that the Gradle daemon was designed for, so let’s see how the numbers look when using it.\n\n#### Clean builds with the Gradle daemon running\n\nThe problem with [JIT compilers](https://en.wikipedia.org/wiki/Just-in-time_compilation), like the JVM, is that they take time to compile code that’s executed on them, and so the performance of a process increases over time as it runs. If you stop the JVM process, that performance gain is lost. When building Java code, you would typically start and stop the JVM every time you build. That forces the JVM to redo work every time you build. To combat this, Gradle comes with a daemon that will stay alive between builds in order to maintain the performance gains from the JIT compilation. You can enable the daemon by passing --_daemon_ to Gradle on the command line, or by adding _org.gradle.daemon=true_ to your _gradle.properties_ file.\n\nHere’s what the same series of clean builds as above looks like, but with the Gradle daemon running:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*l9HeNTP1a2EFCNUsuMlFow.png)\n\n_Ten consecutive clean builds with the Gradle daemon running_\n\nAs you can see, the first run takes about the same amount of time as without the daemon, but subsequent runs increase in performance until the fourth run. In this scenario, it’s more useful to look at the average build time after the third run, where the daemon is warmed up. For the warm runs, the average time for doing a clean build in Java is 14.1 seconds, while Kotlin clocks in at 16.5 seconds: a 13% increase.\n\n> For clean builds with the Gradle daemon warmed up, Java compiles 13% faster than Kotlin.\n\nKotlin is catching up to Java, but is still trailing behind slightly. However, no matter what language you use, the Gradle daemon will reduce build times by over 40%. If you’re not using it already, you should be.\n\nSo Kotlin compiles a little slower than Java for full builds. But you usually compile after making changes to only a few files, and incremental builds are going to have different performance characteristics. So let’s find out if Kotlin can catch up where it matters.\n\n#### Incremental builds\n\nOne of the most important performance features of a compiler is its use of incremental compilation. A normal build will recompile all source files in a project, but an incremental build will keep track of which files have changed since the last build and only recompile those files and the files that depend on them. This can have a huge impact on compile times, especially for large projects.\n\nIncremental builds were added to Kotlin in [version 1.0.2](https://blog.jetbrains.com/kotlin/2016/05/kotlin-1-0-2-is-here/), and you can enable them by adding _kotlin.incremental=true_ to your _gradle.properties,_ or by [using a command line option](https://kotlinlang.org/docs/reference/using-gradle.html#incremental-compilation).\n\nSo how do Kotlin compile times compare to Java’s when incremental compilation is used? Here are the benchmarks with incremental compilation when no files are changed:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*at-xrjHBLoSOzpGHzobUAA.png)\n\n_Ten consecutive incremental builds with no files changed_\n\nNext, we’ll test incremental compilation with a modified source file. To test this, I changed a java file and its Kotlin equivalent before each build. In this benchmark, the source file is a UI file that no other files depend on:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*pFr_QiMoES45By4FrviSxA.png)\n\n_Ten consecutive incremental builds with one isolated file changed_\n\nFinally, let’s look at incremental compilation with a modified source file, where the file is imported into many other files in the project:\n\n![](https://d262ilb51hltx0.cloudfront.net/max/800/1*X0JgS3Go9vsMcwCe_95gWA.png)\n\n_Ten consecutive incremental builds with one core file changed_\n\nYou can see that the Gradle daemon still takes two or three runs to warm up, but after that the performance of both languages is very similar. With no changes, Java takes 4.6 seconds per warm build, while Kotlin averages 4.5 seconds. When we change a file that isn’t used by any other files, Java requires an average of 7.0 seconds to do a warm build, and Kotlin clocks in at 6.1. And finally, when we change a file that is imported by many other files in the project, Java requires 7.1 seconds to do an incremental build once the Gradle daemon is warmed up, while Kotlin averages 6.0 seconds.\n\n> In the most common configuration — partial builds with incremental compilation enabled — Kotlin compiles as fast or slightly faster than Java.\n\n### Conclusion\n\nWe benchmarked a few different scenarios to see if Kotlin could keep up with Java when it comes to compilation times. While Java does beat Kotlin by 10–15% for clean builds, those are relatively rare. The much more common scenario for most developers is partial builds, where incremental compilation makes large improvements. With the Gradle daemon running and incremental compilation turned on, Kotlin compiles as fast or slightly faster than Java.\n\nThat’s an impressive result, and one that I didn’t expect. I have to commend the Kotlin team for designing a language that not only has a lot of great features, but can compile so quickly.\n\nIf you were holding off on trying out Kotlin because of compile times, you don’t have to worry any more: Kotlin compiles as quickly as Java.\n\n_You can find the raw data I collected for all benchmarks_ [_here_](https://gist.github.com/ajalt/31c4a45001bea4438f313c899fa961a8)_._\n\nInterested in programming Kotlin full time? Apply as a Kotlin Engineer at [Keepsafe](https://getkeepsafe.com/careers.html).\n\n","author":"AJ Alt","date":"2016-09-09","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"FoldingTabBar Comes to Android. Thank You, Google!","url":"https://yalantis.com/blog/foldingtabbar-for-android/","body":"","author":"Andriy Hristyan","date":"2016-12-15","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Feedback on the Josephus problem","url":"https://blog.frankel.ch/feedback-jospehus-problem","body":"\nMy last week [article](https://blog.frankel.ch/solving-the-josephus-problem-in-kotlin) was about the solving the Josephus problem in Kotlin. For ease of comparison, here’s the version I wrote originally:\n\n```kotlin\nclass Soldier(val position: Int) {\n var state = State.Living\n lateinit var next: Soldier\n fun suicide() {\n state = State.Dead\n }\n fun isDead() = state == State.Dead\n}\n\nenum class State {\n Living, Dead\n}\n\nclass Circle(private val size: Int, private val step: Int) {\n\n private val first = Soldier(0)\n\n init {\n var person = first\n while (person.position < size - 1) {\n person = createNext(person)\n }\n val last = person\n last.next = first\n }\n\n private fun createNext(soldier: Soldier): Soldier {\n val new = Soldier(soldier.position + 1)\n soldier.next = new\n return new\n }\n\n fun findSurvivor(): Soldier {\n var soldier: Soldier = first\n var numberOfDead = 0\n while (numberOfDead < size - 1) {\n var count: Int = 0\n while (count < step) {\n soldier = nextLivingSoldier(soldier)\n count++\n }\n soldier.suicide()\n numberOfDead++\n }\n return nextLivingSoldier(soldier)\n }\n\n private fun nextLivingSoldier(soldier: Soldier): Soldier {\n var currentSoldier = soldier.next\n while (currentSoldier.isDead()) {\n currentSoldier = currentSoldier.next\n }\n return currentSoldier\n }\n}\n```\n\nThe post ended with an open question: was the code the _right_ way to do it? In particular:\n\n* Is the code idiomatic Kotlin?\n* Lack of `for` means using `while` with `var`s\n* Too many mutability (`var`) for my own liking\n\nI’ve received great feedback from the community on many different channels, including Ilya Ryzhenkov from JetBrains, Cédric Beust, Peter Somerhoff and Gaëtan Zoritchak. Thanks guys!\n\nI think the most interesting is this one, very slightly modified from the original [Gist](https://gist.github.com/gzoritchak/1e2ec8d38fc39a4485ba) by Gaëtan:\n\n```kotlin\nclass Soldier(val position: Int, var state:State = State.Living) {\n fun suicide() {\n state = State.Dead\n }\n fun isAlive() = state == State.Living\n}\n\nenum class State {\n Living, Dead\n}\n\nclass Circle(val size: Int, val step: Int) {\n\n val soldiers = Array( size, {Soldier(it)}).toList()\n\n fun findSurvivor(): Soldier {\n var soldier = soldiers.first()\n (2..size).forEach {\n (1..step).forEach {\n soldier = soldier.nextLivingSoldier()\n }\n soldier.suicide()\n }\n return soldier.nextLivingSoldier()\n }\n\n tailrec private fun Soldier.nextLivingSoldier():Soldier =\n if (next().isAlive())\n next()\n else\n next().nextLivingSoldier()\n\n private fun Soldier.next() = soldiers.get(\n if (position == size - 1)\n 0\n else\n position + 1\n )\n}\n```\n\nI like this code a lot because it feels more Kotlin-esque. Improvements are many.\n\n* The code is shorter without any loss of readability\n* It’s entirely functional, there’s only a single `var` involved:\n * the 2 `while` loops with their associated `var` counter have been replaced by simple `forEach` on `Int` ranges.\n * Chaining `Soldier` instances is not handled in the `Soldier` class itself through the `next()` method but by the containing `Circle`. Thus, a simple backing array can store them and there’s no need for custom code with mutable variables.\n* The _recursive_ `nextLivingSoldier()` function has been “annotated” with `tailrec` in order for the compiler to run its optimization magic.\n* The `Soldier` class doesn’t know about its container `Circle`‘s `size`, so functions using it have been moved inside the `Circle` class as extension functions to the `Soldier` class. This is a great usage of Kotlin’s extension functions.\n\nThis experience reinforced my belief that learning a language by just reading about it is not enough. To truly make it yours, steps should be those:\n\n1. obviously, learn the syntax of the language – and its API,\n2. code a solution or an app with this language,\n3. ask for feedback,\n4. read, analyze and understand the feedback,\n5. rinse and repeat.\n\n","author":"Nicolas Frankel","date":"2016-03-13","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Developing on Android sucks a lot less with Kotlin","url":"https://wiredcraft.com/blog/android-apps-development-kotlin/","body":"\n![Kotlin](https://wiredcraft.com/images/posts/Android-app-development-Kotlin.jpg)\n\nWhile Android development has improved tremendously in the past few years, many think that it still sucks when compared to iOS. A lot of folks are working hard to make it better, maybe even enjoyable. And [Kotlin](https://kotlinlang.org/), a new programming language, seems to be headed in that direction. Having been brought onboard by Starbucks in China to work on their mobile apps, we've been experimenting with Kotlin as a viable option to improving the UX of the Android app and making it overall more maintainable.\n\n## What is Kotlin?\n\n[Kotlin](https://kotlinlang.org/) is a new language from the guys at JetBrain, the team behind Intellij, Android Studio, and some of the best IDE in the industry. Essentially, Kotlin is an evolution of the Java syntax. Its source code can be compiled to JVM bytecode and it has 100% interoperability with Java. JetBrain even recently added the ability to compile Kotlin code to JavaScript, potentially broadening its reach.\n\n## Who should use Kotlin?\n\nSo, who is Kotlin for? Newbies or experts?\n\nI would argue both.\n\nNewbies can enjoy a cleaner and more concise syntax and avoid a lot of beginner's mistakes people usually run into with Java. Experts will also most likely enjoy the cleaner syntax, and most likely find themselves more productive for it.\n\n## What makes Kotlin different?\n\nIf you hate Java, Kotlin may be your solution. In many ways, it \"fixes\" Java, especially for Android. While the next major release of Java (8) looks pretty promising and brings a lot of modern language features (e.g. lambda and functional programming), there's no official schedule yet for when it will be made available for the Android platform. Kotlin is available right now.\n\nLet's have a what it brings:\n\n### 1. Cleaner syntax\n\nHere's a \"Hello world\" in Kotlin:\n\n```kotlin\nfun main(args: Array) {\n println(\"Hello, World!\")\n}\n```\n\nCompared to Java:\n\n```java\npublic class HelloWorld {\n public static void main(String[] args) {\n //Prints \"Hello, World\" to the terminal window.System.out.println(\"Hello, World\");\n }\n}\n```\n\nI think you'll agree that Kotlin is much cleaner and way more concise.\n\n### 2. Null safety\n\nHow many times did you run into a `Null Pointer Exception` while developing or testing? Kotlin takes all `null` value checks from runtime to compile time. By doing so, it ensures null safety for any code that passes compilation.\n\nFor example, the Java code below can be compiled, but will throw a `Null Pointer Exception` at runtime.\n\n```java\nString a = null;\nSystem.out.println(a.length());\n```\n\nWith Kotlin, variables are not nullable by default. For example, this piece of Kotlin code won't compile:\n\n```kotlin\nval a:String = null\n```\n\nBut if you really want to allow some variable to have null value, you can add a question mark:\n\n```kotlin\nval a: String? = null\nprintln(a?.length())\n```\n\nIn the example above, the first `?` is used to make the variable `a` nullable, the second `?` is just to check if the value of `a` is null.\n\n### 3. Functional programming\n\nOne of the most important changes in Java 8 is lambda. While we're waiting for this to come to the Android platform, Kotlin can already add a lot of high-order functional programming features on top of Java 6.\n\nBy \"high-order,\" I mean a function that can take another function as a parameter or return a function. For example, many programming languages have the `filter` function, which can take a Collection-like data structure and a function to filter the elements in the Collection that doesn't meet certain criteria. Then return a subset of the original Collection.\n\nThis is how you might implement a `filter` function in Kotlin:\n\n```kotlin\nfun filter(items: Collection, f: (T) -> Boolean): List {\n val newItems = arrayListOf()\n for (item in items) if (f(item)) newItems.add(item)\n return newItems\n}\n```\n\nThen you can use it on a Collection data structure:\n\n```kotlin\nfilter(numbers, { value ->\n value >= 5\n})\n```\n\nPretty clean implementation right? Wait, it can be even cleaner by using the special `it` keyword that represents each item inside the collection:\n\n```kotlin\nfilter(numbers) { it >= 5 }\n```\n\n## Minimum overhead\n\nBeyond adding features, the Kotlin language is actually pretty small. For the latest version to this day (`1.0.0-beta-4584`), runtime and standard library are a few kilobytes in size. It won't add much weight to your project.\n\nThe features we mentioned previously are just a few things that Kotlin brings to the table. For more, I suggest checking out the [official reference page](https://kotlinlang.org/docs/reference/).\n\n## Using Kotlin on Android Studio\n\nThe author of Kotlin is also the author of some of the most popular IDE out there. There are official plugins for Eclipse, IntelliJ IDEA, and standalone command line compiler as well. Since we're focusing on Android, here are a few tips for Android Studio:\n\n1. Download and install Intellij IDEA/Android Studio plugin. You can install it through the IDE preference panel or download if from JetBrain site.\n\n![android-studio-Kotlin-development](https://wiredcraft.com/images/posts/Kotlin-android-app-development-2.png)\n\n2. Once you have the plugin installed, you can start using it. If you're trying to convert an existing Java project, simply click `Code → Convert Java File to Kotlin File` in the menu bar. Kotlin will convert the source Java code to Kotlin code. Alternatively, if you're starting a project from scratch, you can create a new Java project and then convert all `.java` files into `.kt` files. Not the best, but hopefully Google and JetBrain will learn to play nice with each other in the future.\n\n![android-studio-Kotlin-development](https://wiredcraft.com/images/posts/Kotlin-android-app-development-3.png)\n\nThat's it!\n\n## Conclusion\n\nKotlin probably isn't as hot in the Android community as Swift is for the iOS world, but the number of libraries is growing. Being interoperable with Java 6 and backed up by JetBrain should put you at ease with investing in it; it will be around for a long time.\n\nKotlin fixed a lot of the issues we had with developing for Android. There's still room for improvement, but I encourage all of you out there who shared the frustrations of building Android apps to give it a try on your next project.\n\nAnd finally, if you're looking for a rock-solid team of nerds and creatives in NYC, Berlin, or Shanghai to work on your next Android or iOS project, [reach out on Twitter](http://twitter.com/wiredcraft) or shoot us an email either [on our site](https://wiredcraft.typeform.com/to/GG4GQz) or at [info@wiredcraft.com](mailto:info@wiredcraft.com).\n","author":"Kuno Qing","date":"2016-03-01","type":"article","categories":["Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Building DSL Instead of an IDE Plugin","url":"http://jonnyzzz.com/blog/2016/09/02/dsl-building/","body":"\nAn alternative way of doing IDE support without any IDE plugin code for not yet supported and specific languages.\n\nProblem Statement\n=================\n\nMost of us use quite smart IDEs daily with languages we use for development. IDE helps us not only\nto highlight keywords. It is able to check types, show errors, do refactoring, complete and analyze code.\n\nOf course we spent some time working with languages that are not (or weakly) supported by an IDE. Those languages\ncould be used for configurations files, logger settings, business rules, scripts, text files and so on.\nThis is a specific domain where a language is used. It can be hard to read code on that language, it can\nbe also hard to write it too. One may easily waste time writing incorrect code.\n\nIt's the lack of decent IDE support for such languages. Let's see how we can solve it\n\nI will use \\\\(Original Language\\\\) term to refer to an unsupported language. \n\nA Trivial Solution\n==================\n\nSay we have an \\\\(Original Language\\\\) we use, and there is no decent support for it in IDE. \n\nThe very first solution is to replace the \\\\(Original Language\\\\) with some other language. \n \nSuppose the \\\\(Original Language\\\\) cannot be thrown away. And it's likely there is a code on that language. \nThere has to be a system that accepts it too.\n\nOkay. We may implement a plugin for our an IDE to support it.\n\nWriting a plugin is a complicated task. One needs to know IDE API. Moreover, you'll implement a parsing \nso that it'd be fast enough to play well in IDE. The parser should also support invalid text input too, e.g. \nincorrect code that is being entered. That can be tricky.\n\nWell, a parser may not be necessary, if, say IDE support some base language, e.g. `.properties` or `.xml` format.\nBut in that case a deep IDE APIs has to be used.\n\nFinally, a plugin will depend on IDE. Meaning it has to be updated to work with newer IDE versions. It's not in\nour control to lock an IDE version.\n\nThis can be done, but, there's an **alternative way**.\n\n\nThe DSL Way\n===========\n\nEveryone uses their IDE. And of course there is a language we use daily. For example, it could be\n[Java](http://www.oracle.com/technetwork/java/index.html),\n[Scala](http://www.scala-lang.org/),\n[Kotlin](https://kotlinlang.org),\n[Go](https://golang.org/), \n[Groovy](http://www.groovy-lang.org/).\nWe know for sure, an IDE is smart on those languages.\n\nMy idea is to an \\\\(Original Language\\\\), which is unsupported by an IDE, into a code in a supported language. \nI will use a \\\\(Target Language \\\\) term for it. Next, run the \ncode to have a code in a \\\\(Original Language\\\\) back. As shown on the diagram below:\n\n![](https://i.imgur.com/w5a5xx5.png)\n\nTo implement it we need \n- \\\\(generator\\\\), a program that reads a valid code in the \\\\(Original Language\\\\) and generates a code in the \\\\(Target Language \\\\)\n- \\\\(API Library\\\\), a peace of code that includes all definition required for a generated code to be more readable\n- \\\\(execute\\\\), a peace of code that makes compiled generated code in the \\\\(Target Language \\\\) to emit a code in the \\\\(Original Language\\\\)\n\nThe goal of those transformations is to have a readable \\\\(Generated Code \\\\). Refactorings for \\\\(Generated Code \\\\) \nin \\\\(Target Language \\\\) are projected to the \\\\(Original Language\\\\). \n\nSelecting a Target Language\n===========================\n\nMost we need from a \\\\( Target Language \\\\) is a decent IDE support.\n \nWe shall select a \\\\( Target Language \\\\) with a good readability for everyone. \nLanguages with better DSL or fluent APIs capabilities are likely to play better.\n\nStatic typing is a nice to have. It makes it harder to make a error. Moreover, \nit's likely to require no setup for an IDE to work. For some dynamic languages\nan additional [helper](https://confluence.jetbrains.com/display/GRVY/Scripting+IDE+for+DSL+awareness) may be required.\n \nThe DSL Way Benefits\n====================\n\nThe DSL Way approach projects all features from an \\\\( Target Language \\\\) into a \\\\(Original Language\\\\). \nWe can say an \\\\(Original Language\\\\) is extended with all possible high-level features of a \\\\( Target Language \\\\).\nFor example, we can use functions, loops, conditions, libraries and so on. There is no need to \nhave a support for such constructs in the \\\\(Original Language\\\\).\nOne may also tune a \\\\(generator\\\\) to say fold duplicates in the input into a loops or functions.\n \nThanks to \\\\(API Library\\\\) we have good readability. It's a creativity part here. But if implemented correctly, \nit improves readability drastically.\n\nThe parsing is easier to implement for The DSL Way approach. We only need to have it supporting valid inputs. By induction,\nwe start with a valid code and generate a valid code. It's way more complex for The IDE Plugin case. \n\nRefactorings and code analysis features for a \\\\(Target Language \\\\) are projected to a \\\\(Original Language\\\\). All \nwhat is needed is to design \\\\(API Library\\\\) and \\\\(generator\\\\) in the right way. Say you need a *find usages* \nfor some domain object. To have it, you may make a \\\\(generator\\\\) declare and use a variable for such entities. \nOnce variables are used, rename feature is implemented for free.\n\nExample\n=======\n\nLet's consider [Log4j](http://logging.apache.org/log4j/1.2/) configuration in `.properties` file as \\\\(Original Language\\\\).\n\n```properties\nlog4j.rootLogger=ERROR,stdout\nlog4j.logger.corp.mega=INFO,stdout\n# meaningful comment goes here\nlog4j.logger.corp.mega.itl.web.metrics=INFO\n\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.layout=org.apache.log4j.PatternLayout\nlog4j.appender.stdout.layout.ConversionPattern=%p\\t%d{ISO8601}\\t%r\\t%c\\t[%t]\\t%m%n\n```\n\nI decided to use [IntelliJ IDEA](https://www.jetbrains.com/idea/) as IDE \nand [Kotlin](https://kotlinlang.org) as \\\\(Target Language \\\\).\n \nThe configuration below can be turned into the following Kotlin code.\n\n```kotlin\nlog4j {\n val stdout = appender(\"stdout\") {\n layout {\n conversionPattern = \"%p\\t%d{ISO8601}\\t%r\\t%c\\t[%t]\\t%m%n\"\n }\n }\n\n rootLogger {\n level = ERROR\n appenders += stdout\n }\n\n logger(\"corp.mega.itl.web.metrics\") {\n level = INFO\n }\n\n logger(\"corp.mega\") {\n level = INFO\n appenders += stdout\n }\n}\n```\n\nThe evaluation of this Kotlin program yields the similar `.properties` file back. \n\nThe DSL code is way easier to read and to write.\n\nThanks to Kotlin static typed DSLs, IntelliJ IDEA understands the code well, warns all incorrect usages,\ncode complete all possibilities. \n\nMoreover, using such DSL is the way to implement automatic tests for your log4j configurations.\nOne may easily setup automatic tests task as a part of their continuous integration, since the code has no dependency on \nan IDE part. \n \nIt opens the way to reuse common configuration files as well as to run. \n\nConclusion\n==========\n\nIn the post we discussed The DSL Way of doing an IDE support **without** writing any IDE related code. \nThe created DSL can be used not only with IDE. It can easily be re-used in any possible applications like code sharing,\nautomatic test, continuous integration and so on.\n\nYou may follow to [this post](http://jonnyzzz.com/blog/2016/03/08/gradle-for-dsl/) for details on how to create decent package\nfor The DSL Way toolset\n\n*PS*. Do you have more examples for \\\\(Original Language\\\\)? Please share in comments below\n\n","author":"Eugene Petrenko","date":"2016-09-02","type":"article","categories":["Kotlin","DSL"],"features":["mathjax","highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Exercises in Kotlin: Part 1 - Getting Started","url":"http://blog.dhananjaynene.com/2016/04/exercises-in-kotlin-part-1-getting-started/","body":"\nKotlin is an exciting new language I have been working with for a couple of months now. I believe it has a lot of features going for it, and I think many will be benefited from learning a bit more about it. Hence this series of posts.\n\nThis post helps you with getting the necessary software installed on your desktop for compiling and running kotlin code\n\n## Presumed Audience :\n\nThe reader is presumed to have a reasonable working knowledge of Java. While one of the reasons Kotlin is particularly exciting is because it is such a useful language for the Android platform, the early parts of this series shall focus on the desktop based JVMs. Since those learnings are common irrespective of whether you wish to use Kotlin for desktop/server or Android programming.\n\nIt is also assumed that the reader has working java development kit installed on his desktop. Most or all of the discussion about syntax will also likely compare Kotlin with Java.\n\n## Information :\n\nSome of the useful sites for Kotlin are\n\n* [Kotlin Programming Language](https://kotlinlang.org/) : Language Home page.\n* [Kotlin Reference](https://kotlinlang.org/docs/reference/) : Reference - Kotlin Programming Language\n* [Intellij Idea](https://www.jetbrains.com/idea/) : IDE with built in kotlin support. From the same authors who bring you kotlin, ie. JetBrains\n* [Kotlin Eclipse Plugin](https://github.com/JetBrains/kotlin-eclipse) : Kotlin plugin for eclipse. _Note: I haven't used it myself_\n\n## Getting started using an IDE\n\n_Note: if you do not prefer to use an IDE and are likely to code using text editors and build and run using command line, you can skip this section entirely and go to [Command Line Usage](#cmdline)_\n\nGo to the Intellij idea page above and download the latest version. You can choose to download the community version. It has the necessary support for Kotlin. You may alternatively choose to use the Eclipse plugin described above, but I haven't used it so cannot help with getting it to work. Install the intellij idea ide and launch it. In case unsure how to do so, consult the [official guide](https://www.jetbrains.com/help/idea/2016.1/installing-and-launching.html) for downloading, installing and launching the ide.\n\nStart a new project. Click on gradle in the left hand column. You should reach the new project dialog box as follows\n\n![Intellij Idea New Project Dialog](http://blog.dhananjaynene.com/images/kotlin/kotlin-1-new-project.png)\n\nI always use the gradle build tool, so I end up making the selections as shown. Select any appropriate JVM between 1.6 and 1.8 (built in one should do). You could use the dialog as shown above. You should next see a dialog box for groupid/artifactid as required by gradle (these mean the same thing as they do for maven, so fill up some group id eg. `com.example.kotlin` and artifactid eg. `learning`). The rest of this post assumes these two values, so if you use different values, please replace them appropriately in the code as necessary.\n\n![Specify groupid and artifactid](http://blog.dhananjaynene.com/images/kotlin/kotlin-3-groupid-artifactid.png)\n\nOn the next two screens you could choose the defaults or customise as necessary\n\n![Project Configuration](http://blog.dhananjaynene.com/images/kotlin/kotlin-4-project-config.png)\n\n![Project Configuration 2](http://blog.dhananjaynene.com/images/kotlin/kotlin-5-project-configuration-2.png)\n\nSince gradle defaults to maven like directory structures, let us create the directory necessary for our work using the groupid/artifactid used earlier and maven conventions. Select the \"_learning_\" folder at the top of the left pane, and select from main or right click menu, File -> New Directory and specify the directory as follows. (If the menu options File -> New Directory do not appear, you have selected the wrong \"_learning_\", select the one at the top of the left pane, not the one in the toolbar above it).\n\n![Create source directory](http://blog.dhananjaynene.com/images/kotlin/kotlin-6-create-directory.png)\n\nSimilarly also create another directory for writing our test cases\n\n![Create test directory](http://blog.dhananjaynene.com/images/kotlin/kotlin-7-create-test-directory.png)\n\nYou should see the appropriate packages for the main and test areas appear in the left hand pane as follows\n\n![IDE View](http://blog.dhananjaynene.com/images/kotlin/kotlin-8-ide-view.png)\n\nRight click on the package name under the src/main/kotlin directory and select \"New Kotlin File/Class\". It will pop up a dialog where you can enter helloworld\n\n![New file dialog](http://blog.dhananjaynene.com/images/kotlin/kotlin-9-new-file-dialog.png)\n\nThis will create a new file \"_helloworld.kt_\" and open it into your ide\n\n![New file](http://blog.dhananjaynene.com/images/kotlin/kotlin-10-new-file.png)\n\nEnter the following code in the just opened file\n\n```kotlin\npackage com.example.kotlin.learning\n\nfun main(args: Array) {\n println(\"Hello World!\")\n}\n```\n\nRun the program using \"Run -> Run\". It will pop up a very small dialog box, select HelloWorldKt from it. (You could also use Alt-Shift-F10 instead of Run -> Run, though not sure if the same key bindings work across operating systems, though thats what it is on Linux). This is the canonical Hello World program for Kotlin. Don't worry about understanding the syntax yet. We will get to it in the very next post, this post is to get you started.\n\nOne more thing to do is to get a sample test case running. So, let us add a function to the file we just created that we shall be testing, as follows\n\n```kotlin\nfun greetings() = \"Hello World!\"\n```\n\nNext, select the package in the src/test/kotlin directory, and after a right click select \"New -> Kotlin File/Class\". This time select the name as \"_testgreet_\", which will create a new file called _testgreet.kt_. Add the following code to the file.\n\n```kotlin\npackage com.example.kotlin.learning\n\nimport org.junit.Test\nimport org.junit.Assert.assertEquals\n\nclass TestGreet() {\n @Test\n fun testGreetings() {\n assertEquals(\"Greeting should be 'Hello World!'\",\n \"Hello World!\", greetings())\n }\n}\n```\n\nAgain select \"Run -> Run...\" or (Alt-Shift-F10 or equivalent). This will pop up a small dialog box. Select TestGreet. This will run the test case and should show an all green bar near the bottom of your IDE as shown in the image below.\n\n![Kotlin Run Test](http://blog.dhananjaynene.com/images/kotlin/kotlin-11-run-test.png)\n\nNow, we shall repeat the exercise using text editors and command line for building and running the program. Even if you _always_ use IDEs, I very much recommend that you at least do the remainder of the activities described on this post at least once. It is always helpful to have a general sense of what is happening at a command line level. However if you skip it, or it doesn't work for you for whatever reason, it won't constrain you from being able to continue with the rest of this series.\n\nIn either case, I shall not be covering the Intellij Idea IDE any further. If you are new to it or to the Eclipse plugin, learning it is beyond the scope of this series of posts, so I encourage you to play around with them, since that is likely to be useful as we go further along in this series.\n\n## Installation for command line usage\n\nThe instructions for working with Kotlin from the command line are documented on the page [Working with the Command Line Compiler](https://kotlinlang.org/docs/tutorials/command-line.html)\n\nGoto [Kotlin latest release](https://github.com/JetBrains/kotlin/releases/latest) to download the Kotlin compiler. It will likely be a file called `kotlin-compiler-.zip`. The current version is 1.0.1-2 at the point in time this post was written. Unzip the file into an appropriate directory. And ensure that the executables kotlin and kotlinc (or their windows equivalent with the .bat extensions) are in your path.\n\nCreate a work directory for this exercise and change directory to it.\n\nCreate a file _helloworld.kt_ with the following content.\n\n```kotlin\npackage com.example.kotlin.learning\n\nfun main(args: Array) {\n println(\"Hello World!\")\n}\n\nfun greetings() = \"Hello World!\"\n```\n\nCompile it using the command\n\n```bash\n$ kotlinc helloworld.kt\n```\n\nNotice that it will have created a file _com/example/kotlin/learning/HelloworldKt.class_. This is the compiled _.class_ file. It is Java byte code though you wouldn't be able to run it as you might be used to just yet. In fact go ahead and try to run it as follows\n\n```bash\n$ java com.example.kotlin.learning.HelloworldKt\n```\n\nIt will fail because you do not have the necessary kotlin runtime jar in your classpath. You should've seen an error message similar to the one below\n\n```kotlin\nException in thread \"main\" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics\n at com.example.kotlin.learning.HelloworldKt.main(helloworld.kt)\nCaused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics\n at java.net.URLClassLoader.findClass(URLClassLoader.java:381)\n at java.lang.ClassLoader.loadClass(ClassLoader.java:424)\n at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)\n at java.lang.ClassLoader.loadClass(ClassLoader.java:357)\n ... 1 more\n```\n\nThat runtime is located in the kotlin zip you had just downloaded. Let us point the classpath to it and attempt to run the program again. (Replace `` below with the appropriate directory where you had unzipped the file you downloaded)\n\n```bash\n$ java -cp /kotlinc/lib/kotlin-runtime.jar:. com.example.kotlin.learning.HelloworldKt\n```\n\nYou should see \"Hello World!\" getting printed to the console. Kotlin provides an easier way to do this as well, so let us repeat the process, just a little differently.\n\nCompile the source again, but this time create a .jar file\n\n```bash\n$ kotlinc helloworld.kt -include-runtime -d helloworld.jar\n```\n\nNow run it as follows\n\n```bash\n$ java -jar helloworld.jar\n```\n\nThe program should run and \"Hello World!\" should get printed to the console.\n\nNow let us run the test case. Create a file _testgreet.kt_ as follows\n\n```kotlin\npackage com.example.kotlin.learning\n\nimport org.junit.Test\nimport org.junit.Assert.assertEquals\n\nclass TestGreet() {\n @Test\n fun testGreetings() {\n assertEquals(\"Greeting should be 'Hello World!'\",\n \"Hello World!\", greetings())\n }\n}\n```\n\nNow for compiling and running this you will need the jar for junit (which in turn requires hamcrest). The instructions for that are provided on the [Download and Install - junit4 wiki](https://github.com/junit-team/junit4/wiki/Download-and-Install) page. For now just go ahead and download the two following jars for junit and hamcrest.\n\n* [junit jar](http://search.maven.org/remotecontent?filepath=junit/junit/4.12/junit-4.12.jar)\n* [hamcrest jar](http://search.maven.org/remotecontent?filepath=org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3.jar)\n\nYou will have downloaded _junit-4.12.jar_ and _hamcrest-all-1.3.jar_. Move both of them into your current directory after download.\n\n```bash\n$ kotlinc helloworld.kt -cp junit-4.12.jar -include-runtime -d helloworld.jar\n```\n\n```bash\n$ java -cp junit-4.12.jar:hamcrest-all-1.3.jar:helloworld.jar org.junit.runner.JUnitCore com.example.kotlin.learning.TestGreet\n```\n\nYou should see something like the follows (the time obviously could vary) that indicates success.\n\n```kotlin\nJUnit version 4.12\n.\nTime: 0.004\n\nOK (1 test)\n```\n\nYou should also be aware that Kotlin has a REPL that you can run using the command `kotlinc-jvm` as follows\n\n```kotlin\n$ kotlinc-jvm\nWelcome to Kotlin version 1.0.1-2 (JRE 1.8.0_77-b03)\nType :help for help, :quit for quit\n>>> println(\"Hello World!\")\nHello World!\n>>>\n```\n\nCongratulations you are now able to compile and run Kotlin programs. In the next post in this series, we shall attempt to understand the code that we just wrote, and explore the Kotlin language further.\n\n","author":"Dhananjay Nene","date":"2016-04-18","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.0: The good, the bad and the evident.","url":"https://jaxenter.com/kotlin-1-0-the-good-the-bad-and-the-evidence-124041.html","body":"\n\nKotlin 1.0 is a programming language made by JetBrains, the creator of the popular IntelliJ IDEA development environment. This programming language for the JVM and Android focuses on safety, interoperability, clarity and tooling support and combines OO and functional features.\n\nAfter a long wait, Kotlin 1.0 is finally here! According to the [official announcement](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/), ” Kotlin works everywhere where Java works: server-side applications, mobile applications (Android), desktop applications. It works with all major tools and services such as IntelliJ IDEA, Android Studio and Eclipse, Maven, Gradle and Ant, Spring Boot, GitHub, Slack and even Minecraft.”\n\nInteroperability and seamless support for mixed Java+ Kotlin projects has been a focal point in the making of this project. Adoption is easier, which leads to less boilerplate code and more type-safety. Plus, the new programming language has a huge standard library which makes daily tasks not only easy, but also smooth while maintaining the byte code footprint low. Kotlin has been dubbed a ‘pragmatic’ programming language because in its creation developers focused on use cases to transform it into a good tool. Utility was the idea behind Kotlin 1.0, as emphasized by Andrey Breslav, the lead language designer of Kotlin: ” the less our users have to re-learn, re-invent, re-do from scratch, the more they can re-use, the better.”\n\nBreslav explained that Kotlin 1.0 is mature enough and ready for production because the team has been using it in real-life projects on a broad scale over the past couple of years and pointed out that a handful of other companies have been using this new programming language in production “for some time now.” The lead language designer of Kotlin revealed that the reason why it took so long for them to produce 1.0 was that they paid extra attention to validating their design decision in practice.\n\nThe team has kept Kotlin’s development very open since 2012 and has continuously talked to the community, collecting and addressing lots of feedback. Breslav announced that they are planning to establish a centralized venue for design proposals and discussions in order to make the process even more organized and visible. The team’s goals in the near future are to offer constant performance improvements for the Kotlin toolchain, JavaScript support and support generating Java 8 byte code.\n\n## The good about Kotlin\n\nMike Hearn, a former bitcoin core developer who recently made waves when he declared that the bitcoin project had “failed”, wrote in a post on [Medium](https://medium.com/@octskyward/why-kotlin-is-my-next-programming-language-c25c001e26e3#.w9lbw7fso) last July that Kotlin is the programming language he will probably use for the next five to 10 years. He opined that Kotlin is “of greatest interest to people who work with Java today, although it could appeal to all programmers who use a garbage collected runtime, including people who currently use Scala, Go, Python, Ruby and JavaScript.”\n\nAccording to Hearn, this programming language “comes from industry, not academia and solves problems faced by working programmers today.” It is open source, approachable and can be learned in a few hours by reading the language reference. “The syntax is lean and intuitive. Kotlin looks a lot like Scala, but is simpler,” he added. It allows developers to continue to use their productivity enhancing tools and adopting it is low risk because “it can be trialled in a small part of your code base by one or two enthusiastic team members without disrupting the rest of your project.”\n\n## The bad: pre-1.0\n\nAs Breslav remarked in the official announcement, the team took their time before they released Kotlin 1.0 because they paid extra attention to validating their design decision on practice. Therefore, all the problems pointed out by Hearn in his review of Kotlin should not exist anymore now that Kotlin 1.0 has been released. The former bitcoin core developer pointed out that Kotlin’s biggest problems were its immaturity (because it was a pre 1.0 language) and that sometimes the requirements of Java interop resulted in unintuitive limitations.\n\nHearn also criticized the size of the community, which was smaller at that time. However, according to Breslav, over 11.000 people were using Kotlin last month and almost 5.000 earlier this month. Plus, there is a growing list of companies using Kotlin, including Expedia and Prezi.\n\nLanguage docs and tutorials can be found on the [official website](https://kotlinlang.org/).\n\n","author":"Gabriela Motroc","date":"2016-02-16","type":"article","categories":["Kotlin","Review"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin: Practical Experience","url":"http://blog.scottlogic.com/2016/04/04/practical-kotlin.html","body":"\nKotlin 1.0.0 was officially released in February this year. Kotlin is a new language from JetBrains (of IntelliJ IDEA and ReSharper fame). It was originally announced in 2011 when a development version was made available to the public. While it can be compiled to JavaScript, the primary target is the JVM, and one of its core goals is 100% Java interoperability.\n\nI have spent some time recently experimenting with Kotlin. There are many features of the language to enjoy when comparing against Java, terseness being high in the list. However, this post primarily serves to highlight a few gotchas that caught me out in the hopes that others may save some time when dealing with similar issues. While this may seem a slightly negative approach for a blog post, my goal is to offer a more practical take instead of only mentioning all the cool things you can do.\n\nI really like Kotlin, I think it has a place in Java development regardless of whether you’re writing server-side or client-side, and regardless of your Java version. Kotlin’s internal API is based on Java 6 which allows Kotlin to be compatible with Android.\n\n## Java 8 Compatibility\n\nAs mentioned, Kotlin is internally dependent on Java 6, which places restrictions on what Java library types and language features Kotlin itself can use. This means any new types and methods added in Java 7 or 8 are not available to the Kotlin standard library, however if your target VM is Java 8 then your Kotlin code can make use of the newer Java features.\n\n### Java 8 Streams\n\nA major addition that was introduced by Java 8 was the Stream API. This API typically makes full use of Java 8’s lambdas to allow users to write code similar to .NET’s LINQ. Since Kotlin is compatible with Java 6, they offer an equivalent through their standard library so that it is available regardless of the underlying version of Java. Below is a simple comparison of the Java 8 stream API and Kotlin’s equivalent standard library:\n\n```java\nList list = new ArrayList<>();\nfor (int i = 0; i < 50; i++) {\n list.add(i);\n}\n\nList filtered = list.stream()\n .filter(x -> x % 2 == 0)\n .collect(toList());\n```\n\n```java\nval list = (0..49).toList()\nval filtered = list\n .filter( { x -> x % 2 == 0 } )\n```\n\nThere are a few things about Kotlin lambdas that I found confusing at first. Lambdas must always appear between curly brackets. This can make the lambda look like a standard block, but once you get used to it, it starts to make sense. There are a few special cases that can be applied to the code above to simplify it further. If the last argument to a method is a lambda, then the lambda definition can be moved outside of the method parentheses, and if the remaining method parentheses are then empty, they can be removed. Furthermore, if the lambda has a single parameter then the parameter declaration can be removed along with the arrow, and the parameter can be referred to by `it`. Applying these rules to the code above simplifies it as follows:\n\n```kotlin\nval list = (0..49).toList()\nval filtered = list\n .filter { it % 2 == 0 }\n```\n\nA key thing to be aware of is that the code shown above is entirely implemented by the Kotlin standard libraries and is therefore independent of Java 8 streams. This is achieved through standard library extension methods.\n\n#### Lazy Streams\n\nThere are subtle differences between the Java and Kotlin code above. Java is using lazy streams - the filter lambda is only applied once the call to `collect` is made. The Kotlin example however is eager, which is why the call to filter immediately returns a list.\n\nThere are ways to make Kotlin lazy, the main option would be to first convert the list to a `Sequence` and apply the lambdas to that instead. Sequences are evaluated lazily allowing a pipeline to be defined before the underlying lambdas are executed. The Kotlin code would then be as follows:\n\n```kotlin\nval list = (0..49).toList().asSequence()\n .filter { it % 2 == 0 }\n .toList()\n```\n\nThis is only worth considering if the pipeline consists of more than the filter operation.\n\n#### Parallel Streams\n\nSomething I ran into was the wish to use Java 8’s parallel streams. Kotlin’s standard library does not include its own parallel stream mechanism, and it is not clear where to start when consulting Kotlin’s standard library.\n\nIn Java one would either call `List.parallelStream()` or call `parallel()` directly on a stream. The subsequent pipeline will then be applied in parallel, and the results collected at the end. The issue is that typically in Kotlin lists are referenced via the Kotlin collection interfaces, even if the runtime instances are actually plain Java classes. This means the following code would not compile because the Kotlin collection interfaces do not know about the `stream()` methods or `Stream` interface.\n\n```kotlin\nlistOf(\"One\", \"Two\", \"Three\").parallelStream()\n```\n\nConsidering these are Java 8 classes means it’s not surprising that there is currently no way for Kotlin to include a stream equivalent in their standard library - doing so would require them to reimplement a Kotlin stream equivalent for supporting Java 6 and 7, and then somehow have it use Java 8’s Stream API if running under a Java 8 VM. In fact Kotlin used to have their own `Stream` type before Java 8, but replaced it with `Sequence` shortly before finalising the 1.0.0 release.\n\nOne workaround is to implement extension methods for the `kotlin.collections.Collection` interface as follows:\n\n```kotlin\nfun Collection.stream(): Stream {\n @Suppress(\"PLATFORM_CLASS_MAPPED_TO_KOTLIN\", \"UNCHECKED_CAST\")\n return (this as java.util.Collection).stream()\n}\n\nfun Collection.parallelStream(): Stream {\n @Suppress(\"PLATFORM_CLASS_MAPPED_TO_KOTLIN\", \"UNCHECKED_CAST\")\n return (this as java.util.Collection).parallelStream()\n}\n```\n\nThis will allow the `stream()` and `parallelStream()` methods to be invoked directly on any Kotlin collection. Note the nasty suppression of warnings though. Firstly IDEA provides a generally good hint that you should probably not be using the `java.util.Collection` class directly - this is because it is normally hidden behind the Kotlin collection interfaces. The second warning is the unchecked cast which is unavoidable - the main issue is the generic type T which has been erased by Java. It is not possible to use Kotlin’s inlined reification feature in these methods either because we’re referring to the Java type that is already erased. This workaround is referenced from a [bug-report](https://youtrack.jetbrains.com/issue/KT-5175) posted for Java 8 streams on Kotlin’s bug tracker. This issue was posted when Kotlin still had its own `Stream` class. While the issue is not resolved (a subsequent release of Kotlin may see a more elegant solution), the removal of Kotlin’s `Stream` class makes the above workaround possible.\n\nAnother issue arises when collecting the results. In Java I would collect a stream to a list using `collect(Collectors.toList())`, Java is usually able to infer the types correctly, however because we’re using Kotlin which defines its own collection types, things are not as smooth. Here is a function definition that uses the `stream()` extension method defined above:\n\n```kotlin\nfun toIntList(strings:List):List {\n return strings.stream()\n .map { it.toInt() }\n .collect(Collectors.toList())\n}\n```\n\nThe trick is to just make the type explicit when using `Collectors.toList`. There are some alternative workarounds posted to this [Stack Overflow question](http://stackoverflow.com/questions/35721528/how-can-i-call-collectcollectors-tolist-on-a-java-8-stream-in-kotlin/35722167#35722167). The update message posted claiming the issue is fixed in Kotlin 1.0.1 is not entirely accurate - I still find I need to make the types explicit when using collectors.\n\n### SAM Types\n\nA nice feature demonstrated in the above code is the fact that Kotlin lambdas are compatible with Java’s Single Abstract Method (SAM) interfaces. This can be seen above where a Kotlin lambda is supplied directly to Java’s `Stream.map` method. The Kotlin compiler automatically generates an adapter function to convert the Kotlin lambda to the desired SAM interface type. Sometimes however this requires a bit of assistance, especially to resolve ambiguity. An example is when using Java 8’s `CompletebleFuture`:\n\n```kotlin\nfun get(url:String, ex: Executor):CompletableFuture {\n return CompletableFuture.supplyAsync( Supplier { downloadURL(url) }, ex)\n}\n```\n\nThis method takes a string and Java executor, and returns a `CompletableFuture` containing the URL’s content. It assumes there is a synchronous `downloadURL` method available. Because the `supplyAsync` Java method takes the lambda as the first parameter, followed by the executor parameter, we can’t use the Kotlin shortcut of pushing the lambda outside of the `supplyAsync` parentheses. To create the correct SAM we prefix the Kotlin lambda with the name of the SAM type we require - in this case a `java.util.function.Supplier`.\n\n### Try-with-resources\n\nThis is actually a Java 7 feature, but still applies when using Java 8. In Java we may do the following to copy from an input stream to an output stream. This example relies on Guava to save some nasty iteration, but demonstrates how in Java we can declare multiple `AutoCloseable` instances in a single try-with-resources declaration. When the try block completes, `AutoCloseable.close()` will be called on each reference.\n\n```kotlin\ntry (InputStream input = new FileInputStream(\"SourceFile\"); OutputStream output = new FileOutputStream(\"TargetFile\")) {\n ByteStreams.copy(input, output); // using Guava\n}\n```\n\nKotlin’s approach is not to add special language constructs, but instead to provide an API: `use()` is simply an extension method on `Closeable`. The following code is the Kotlin equivalent:\n\n```kotlin\nFileInputStream(\"SourceFile\").use { input ->\n FileOutputStream(\"TargetFile\").use { output ->\n input.copyTo(output)\n }\n}\n```\n\nNote that we have to nest the second `use` method call to include the second resource declaration, which also means we can’t use the implicit `it` parameter because we have to differentiate between `input` and `output`.\n\nWe also cannot use `AutoCloseable` which was only introduced in Java 7, so this restricts the usage to `Closeable` implementations only. The only workaround for the `AutoCloseable` case at the moment is to implement one’s own `use` extension method for `AutoCloseable`. JetBrains have indicated they are looking at this, though this goes back at least to 2014. I guess it wasn’t seen as something that had to be fixed by 1.0.0, especially since a proper fix introduces the need for Kotlin to be able to target newer versions of Java as well as keep working for Java 6.\n\nAnother issue is that `use` is currently not able to use `Throwable.addSuppressed(Thowable)` for the case where an Exception is being thrown but the close call in the finally block throws its own exception, because this method was also only added in Java 7 specifically for supporting the try-with-resources construct. The source for Kotlin’s `use` includes a TODO item for this and correctly swallows the exception from close so that it doesn’t mask the original exception, hopefully a better solution will be forthcoming. This issue is [discussed here](https://discuss.kotlinlang.org/t/kotlin-needs-try-with-resources/214).\n\n## Java Annotations\n\nThis is one particular case I encountered when trying to use Java’s XML binding API (JAXB), however this would affect other annotation processing libraries as well.\n\nConsider the following Kotlin class:\n\n```kotlin\n@XmlRootElement(name = \"contact\")\ndata class Contact(\n @XmlAttribute var firstName:String? = null,\n @XmlAttribute var lastName: String? = null\n)\n```\n\n\nI have already tried to cover the basics: by making all the fields nullable and providing null as the default argument, the resulting class will have an empty constructor, as required by JAXB. I have also annotated the root element, and the attributes. But when I try and parse an XML file, I see the following trace:\n\n```kotlin\nException in thread \"main\" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions\nClass has two properties of the same name \"firstName\"\n this problem is related to the following location:\n at public final java.lang.String blog.Contact.getFirstName()\n at blog.Contact\n this problem is related to the following location:\n at private java.lang.String blog.Contact.firstName\n at blog.Contact\nClass has two properties of the same name \"lastName\"\n this problem is related to the following location:\n at public final java.lang.String blog.Contact.getLastName()\n at blog.Contact\n this problem is related to the following location:\n at private java.lang.String blog.Contact.lastName\n at blog.Contact\n```\n\nIt looks like the attribute annotation is being applied to both the public getter as well as the private field, for both the `firstName` and `lastName` properties. This is primarily fallout from Kotlin’s conciseness. In the `Contact` class above, the parameters are both constructor arguments as well as property declarations. Since a Kotlin property will be compiled into a getter, setter and backing field, the annotations are applied based on a choice from the Target annotation from the underlying annotation implementation. The best workaround here was to be explicit about what the `XmlAttribute` annotation should apply to - this can be done using annotation use-site targets as follows:\n\n```kotlin\n@XmlRootElement(name = \"contact\")\ndata class Contact(\n @get:XmlAttribute var firstName:String? = null,\n @get:XmlAttribute var lastName: String? = null\n)\n```\n\nInserting `get:` before the annotation name will apply the annotation to the Java getter method, and this resolves the annotation/field clash. The full list of use-site targets can be found [here](https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets).\n\nOne more thing I found - for this simple case it is possible to fix the issue by adding `@XmlAccessorType(XmlAccessType.FIELD)` to the root element instead, however once I had more complex XML the `IllegalAnnotationsException` would just be pushed down to one of the deeper classes.\n\n## Type-Safe Builders\n\nOne of the features of Kotlin that caught my eye at the start was the concept of type-safe builders. The example included in the [official documentation](https://kotlinlang.org/docs/reference/type-safe-builders.html) shows how an HTML document can be built. Once you have the builder code in place, you can use it as follows:\n\n```kotlin\nval html = html {\n head {\n title { +\"Document Title\" }\n }\n body {\n h1 { +\"A Nice H1 Heading\" }\n p {\n +\"The wordy first paragraph including a \"\n a(href = \"http://kotlinlang.org\") { +\"link\" }\n b { +\" as well as some bold text\" }\n }\n }\n}\n```\n\nI liked this because the structure of the resulting document was reflected in the structure of the code. This is made possible by a combination of features:\n\n* Lambdas must always be defined between curly braces.\n* If the last argument to a method is a lambda, it can be appended after the method parentheses (which in turn can be omitted when empty).\n* _Function type with receiver_ lambda arguments.\n\nLooking at the example code again in light of these 3 features, the code is actually just a set of nested method invocations taking a lambda as a parameter. Each lambda is a function type with receiver, which is similar to an extension function. The receiver (`this`) can be optionally omitted as it can with an extension method.\n\nIt took me a bit of effort to understand initially, so I suggest reading the official documentation to get a better idea. Once I understood the underlying concepts I was ready to start writing my own set of builders to support creation of a UI. This is where I came up against an issue with the type-safe builder pattern.\n\nThe issue is as follows - each time you define a nested lambda, it collects the scope of its parent invocations - all the way to the root. In the html example above, it means that the following will compile and generate no warnings, but the result will be confusing:\n\n```kotlin\nhtml {\n head {\n title { +\"Document Title\" }\n }\n body {\n h1 { +\"A Nice H1 Heading\" }\n p {\n +\"The wordy first paragraph including a \"\n body {\n h1 { +\"This is unexpected\" }\n }\n a(href = \"http://kotlinlang.org\") { +\"link\" }\n b { +\" as well as some bold text\" }\n }\n }\n}\n```\n\nYou can see I’ve added an extra `body` call within the deepest `p`. From thinking of this as a type-safe builder of an html document, this should not be possible, since it should not be possible to add a body element at that level. It would be nice if compilation failed. However, if we forget about the html side of things, and just think of this as a bunch of nested closures, then it makes sense. A closure has access to the variables of the outer scope in addition to the current scope. This nested closure effectively has implicit access to all the `this` keywords up the chain. If we explicitly insert the qualified `this` keywords, it looks as follows:\n\n```kotlin\nhtml {\n this.head {\n this.title { +\"Document Title\" }\n }\n this.body {\n this.h1 { +\"A Nice H1 Heading\" }\n this.p {\n +\"The wordy first paragraph including a \"\n this@html.body {\n this.h1 { +\"This is unexpected\" }\n }\n this.a(href = \"http://kotlinlang.org\") { +\"link\" }\n this.b { +\" as well as some bold text\" }\n }\n }\n}\n```\n\n\nYou can see the qualified `this@html` reference - this is also implicitly available, but the point is that the second `body` invocation is actually being made against the root html instance, and not against the the paragraph instance that is implied. This leads to the following html document being generated:\n\n```html\n\n \n \n Document Title\n \n \n \n

    \n This is unexpected\n

    \n \n \n

    \n A Nice H1 Heading\n

    \n

    \n The wordy first paragraph including a\n \n link\n \n \n as well as some bold text\n \n

    \n \n\n```\n\nThe reason the second `body` actually appears first is because the nested body is completed (and added to the document) before the first `body` is completed. This is confusing behaviour and is unfortunately simply the result of Kotlin’s closures behaving correctly. A workaround may be to prefix all the invocations by the unqualified `this` keyword. If you do this you will find a compiler error is then generated when you try make a call to `this.body` from inside `p`, however the resulting code looks messier, and it is still possible to forget the `this` prefix.\n\nI’ve only found the following Stack Overflow question and answer [here](http://stackoverflow.com/questions/34834739/wrong-this-being-used-in-nested-closures#34836287), where the principle engineer at JetBrains confirms the issue, and hints that a future Kotlin version may add a modifier to restrict a lambda from having access to enclosing scopes.\n\nI may wait and see where this goes before embracing type-safe builders. I like the idea - especially how it could be used to implement a DSL for creating a UI, however I think this would cause a usage issue.\n\n## Conclusion\n\nOverall I have had a very positive experience. I quickly adapted to the Kotlin syntax and enjoyed using it. The issues I’ve raised in this post should not be viewed in a negative light - for every issue I’ve raised here there are countless times I found myself impressed at how Kotlin integrates cohesively with Java. My main reason for creating this post is to collect my experiences for future reference, and hopefully to help people who run into the same issues.\n\n\n\n","author":"Allen Wallis","date":"2016-04-04","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Performance comparison - building Android UI with code (Anko) vs XML Layout.","url":"https://nethergrim.github.io/performance/2016/04/16/anko.html","body":"\nHi!\n\nThis is my first blog post.\n\n## Intro\n\nHere I will be talking about difference in performance between using XML layouts and [_Anko_](https://github.com/Kotlin/anko) to build UI for _Android_ apps.\n\nAs you may know, _Anko_ is a new DSL for Android, written in [_Kotlin_](https://kotlinlang.org/). It helps a lot to develop _Android_ apps using _Kotlin_ lang. _Anko_ provides various handy features, and my favorite is building ui with code. Yeah, you can tell me that we can also build user interface using _Java_, and create all Views in code, but it is ugly and hard to maintain.\n\n## The problem\n\nBy default, UI in _Android_ is built using XML layout files. This is inconvenient because it is not typesafe, not null-safe, and it leads to overhead in **cpu** and **ram** usage. It can be insensibly for fast and powerful devices, but low-end devices may suffer from resources deficit. The more Views you have in your xml layout file, the more time it takes to:\n\n* inflate view from XML file\n* create view objects\n* find views by id with [_findViewById_](http://developer.android.com/intl/ru/reference/android/view/View.html#findViewById(int))\n\nNow imagine, that you need to perform that actions for multiple layouts, for example if you need to display list of items. In this case android will perform every step of those 3, for every list item in your UI. It will be even worse if every list item have more than 5-7 views. More views you have, more time it takes to display them.\n\nBy using _Anko_ (or creating Views programmatically, even with _Java_) we can remove 2/3 of that work:\n\n* ~~inflate view from XML file~~\n* create view objects\n* ~~find views by id with [_findViewById_](http://developer.android.com/intl/ru/reference/android/view/View.html#findViewByIdn(int))~~\n\nAlso it is easy to create UI with _Anko_, if you’re familiar with android _Layouts_.\n\n## Benchmark\n\nFor benchmark i will use two Activities, with two similar lists of users. I think it is a typical case for _Android_ apps. For every list item i will be using RelativeLayout with 4 views inside:\n\n* user avatar (using [_Fresco_](http://frescolib.org/))\n* user name\n* user title\n* last seen date\n\nAfter that i will measure [_onCreateViewHolder_](http://developer.android.com/intl/ru/reference/android/support/v7/widget/RecyclerView.Adapter.html#onCreateViewHolder) method execution time for every item.\n\n![device](https://cloud.githubusercontent.com/assets/5869863/14586400/8b257a58-049f-11e6-8e72-14f78753c53b.png)\n\n### Benchmark results\n\nWell, i tested both cases on these devices:\n\n* android emulator on MacBook pro 15 2015\n* Meizu mx-5\n* THL w8 (low end)\n* Nexus 6 Marshmallow\n* Meizu mx-4\n* Samsung Galaxy S2 Plus\n* Samsung Galaxy S3\n* Samsung Galaxy J5\n\nAll values are in milliseconds, that needed for _onCreateViewHolder_ method to execute inside the RecyclerView adapter.\n\n> Please note that frames on Android are drawing every 16 milliseconds, and if any frame will not be able to draw in that period, it will draw after 32/48/64... ms, and this is called dropped frames. So every time your frame takes >16ms to draw, it is dropped. Also note that your UI thread will have more work than just drawing frames, it need to handle all user input, and execute all of your code too. It means that less milliseconds to draw is better for us.\n\nAnd here is what i got:\n\n![2016-04-18 17 13 40](https://cloud.githubusercontent.com/assets/5869863/14607128/f77fa9b4-0588-11e6-9fcc-4884ad6d709a.png)\n\n[Macbook XML results](https://cloud.githubusercontent.com/assets/5869863/14587122/984e5338-04b5-11e6-8dd3-f953a0c2d03a.png) * [Macbook Coded results](https://cloud.githubusercontent.com/assets/5869863/14587125/b5fb4332-04b5-11e6-9b59-71c38f5bd2d0.png)\n\n[Meizu MX5 XML results](https://cloud.githubusercontent.com/assets/5869863/14587130/c8315e24-04b5-11e6-84d7-8a943e386691.png) * [Meizu MX5 Coded results](https://cloud.githubusercontent.com/assets/5869863/14587140/0143ddf4-04b6-11e6-98dd-940e89ae141e.png)\n\n[Thl W8 XML results](https://cloud.githubusercontent.com/assets/5869863/14587146/2fe107ae-04b6-11e6-8f25-5bc901d88780.png) * [Thl W8 Coded results](https://cloud.githubusercontent.com/assets/5869863/14587153/42b90c8c-04b6-11e6-8fba-6f8fec4c0b75.png)\n\n[Nexus 5 XML results](https://cloud.githubusercontent.com/assets/5869863/14587159/54031f5a-04b6-11e6-9b18-3ebd6b1e7a90.png) * [Nexus 5 Coded results](https://cloud.githubusercontent.com/assets/5869863/14587160/617e05aa-04b6-11e6-8082-ee802e5ebf4d.png)\n\n[Meizu MX4 XML results](https://cloud.githubusercontent.com/assets/5869863/14587163/75c93db8-04b6-11e6-870c-44dfcda0dc0e.png) * [Meizu MX4 Coded results](https://cloud.githubusercontent.com/assets/5869863/14587167/87feb06c-04b6-11e6-9b90-8c7549554292.png)\n\n[Galaxy S2 Plus XML results](https://cloud.githubusercontent.com/assets/5869863/14607148/10f5da3a-0589-11e6-8493-e81a92dddd38.png) * [Galaxy S2 Plus Coded results](https://cloud.githubusercontent.com/assets/5869863/14607158/1b9d5d32-0589-11e6-8185-db11a263e2ca.png)\n\n[Galaxy J5 XML results](https://cloud.githubusercontent.com/assets/5869863/14602312/e072d2be-056f-11e6-9ec0-2a23799b6911.png) * [Galaxy J5 Coded results](https://cloud.githubusercontent.com/assets/5869863/14602328/f7fb5d84-056f-11e6-86fd-1d0169a0ef45.png)\n\n[Galaxy S3 XML results](https://cloud.githubusercontent.com/assets/5869863/14602338/0bbfc29c-0570-11e6-9189-977387de5c3d.png) * [Galaxy S3 Coded results](https://cloud.githubusercontent.com/assets/5869863/14602353/1d4b2498-0570-11e6-858c-586957d4784b.png)\n\n## Conclusion\n\nAs I thought, building User Interface on Android is faster with code, than with XML layout files. And this is true for all kind of devices/sdk’s.\n\nWe can see up to **300%** performance boost here.\n\nThere is not a big (relatively) boost on high-end devices, but low-end devices can have huge boost using coded ui.\n\n_Should we use coded UI everywhere?_ - **Only if you are using Kotlin, and you have some extra time for optimizations**\n\n_Should we use it if we have large amount of Views into single list item?_ - I would say **YES**\n\n_Should we use it if our customer has low-end device, and says that app is freezing all the time?_ - Answer will be **yes** too.\n\nSource code can be found [HERE](https://github.com/nethergrim/anko_benchmark)\n\nP.S. You can try that benchmark by **yourself**, on your device. Just check the [repo](https://github.com/nethergrim/anko_benchmark)\n\n\n","author":"Andrew Drobyazko","date":"2016-04-16","type":"article","categories":["Kotlin","Anko","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Costruiamo un treno in Kotlin","url":"https://www.youtube.com/watch?v=y-T6DCtNUG0","body":"\nDopo cinque anni di sviluppo JetBrains rilascia la prima versione di Kotlin, linguaggio staticamente tipizzato che pur rimanendo pienamente compatibile con Java cerca di risolverne alcuni problemi tutt'ora aperti. Presenterò un semplice programma realizzato con approccio OO/funzionale e confronteremo l'implementazione Java 8 con quella Kotlin.\n\nFrancesco Vasco: Lavoro da 16 anni in varie realtà utilizzando prevalentemente tecnologie in ambito Java e da febbraio ho iniziato ad utilizzare Kotlin sia in campo amatoriale che professionale.\n\n[JUG Milano meeting #86](http://www.jugmilano.it/meeting-86.html)\n\n\n","author":"Francesco Vasco","date":"2016-12-19","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"IT","enclosure":null},{"title":"Kotlin: New Hope in a Java 6 Wasteland","url":"https://speakerdeck.com/pardom/kotlin-new-hope-in-a-java-6-wasteland","body":"\n\n[Slides](https://speakerdeck.com/pardom/kotlin-new-hope-in-a-java-6-wasteland)\n\n","author":"Michael Pardo","date":"2015-05-09","type":"slides","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"More Kotlin Extension Fun","url":"http://oneeyedmen.com/more-kotlin-extension-fun.html","body":"\nThis is a follow-up to my last post, [Extension Functions Can Be Utility Functions](http://oneeyedmen.com/extension-functions-can-be-utility-functions.html). Here I’ll look at more pros and cons of extension functions.\n\nThe article brought out 3 extension function use-cases.\n\n1. Adding a little local expressiveness with private methods like `JsonNode.toAddress()`\n2. Adding methods you wish were available on types that you don’t own - `JsonNode.getNonBlankText(name: String)`\n3. Keeping your own classes small by defining operations as extension functions rather than actual methods - `AccessType.toUIString()`\n\nOn the Kotlin Slack Channel, Daniel Wellman asked\n\n_“How do you decide when methods should be extension functions and when they should be members (functions) on classes/objects _that you own_?”_\n\nNathan Armstrong replied\n\n_“I think it’s usually when it encapsulates operations on a type in some context tangential to the one the type was made for. For example, when writing code that intersects two domains or concerns, using extension methods can help you use your existing types more naturally alongside one another without leaking that local utility into other parts of the codebase”_\n\nHe’s right. So right that I’m going to say that again with many more words and claim the credit.\n\nMost of my Java projects have ended up with a package of domain objects - `Person`, `Address` etc. Kotlin makes these nice and simple with data classes, and when 1.1 allows inheritance these will become even more useful.\n\nOver time these classes accrete operations that make sense to our application. Things like `Person.asJson()` and `Address.isCloseMyHouse()`. These operations dilute the essence of the class for our happy convenience, but after a while we can’t see the platonic wood for expedient trees.\n\nExtension functions let us express the PersonNess in the `Person` class, and the JSONness elsewhere. In this case maybe type-classes would be better, but for now, we can move our JSON writing and useful-to-us-but-not-really-essential operations off of the class and into extension functions.\n\nA nice side-effect of this is that we can build our domain classes in a module that doesn’t have dependencies on Jackson and some SQL library and the whole of the rest of our app. Maybe we’ll finally get reuseable abstractions for those fundamental real-world things that every app has to implement from scratch because of all the special cases that define our Customer rather than yours.\n\nA word of warning though. Extension functions are not polymorphic. If I have\n\n```kotlin\nclass Person\n\nclass Customer: Person\n\nfun Person.toJson() = ...\n\nfun Customer.toJson() = ...\n```\n\nthe bindings are as follows:\n\n```kotlin\nPerson().toJson() // calls Person.toJson()\n\nCustomer().toJson() // calls Customer.toJson()\n\nval person: Person = readCustomer(42)\nperson.toJson() // calls Person.toJson() no matter what the actual type of person\n```\n\nIf you like this, [Nat Pryce](http://www.natpryce.com) and I are going to be talking about Expressive Kotlin at the [Kotlin Night London](https://info.jetbrains.com/Kotlin-Night-London.html) next Wednesday, 12 October 2016.\n\nThanks to [Springer Nature](http://www.springernature.com) for allowing me to publish examples from their code. If you’re looking for a Kotlin job in London, they are hiring - please contact me using one of the links in the sidebar.\n\n","author":"Duncan McGregor","date":"2016-10-06","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1 Released with JavaScript Support, Coroutines and more","url":"https://blog.jetbrains.com/kotlin/2017/03/kotlin-1-1/","body":"\nMembers of our community have translated this blog post into several languages:\n[![](https://i1.wp.com/emojipedia-us.s3.amazonaws.com/cache/82/1a/821aaf51852412ffcf042c2f2a61309e.png?w=25&ssl=1)](https://medium.com/@walmyrcarvalho/kotlin-1-1-suporte-a-javascript-co-rotinas-e-mais-d84b65ac2f92)\n[![](https://i1.wp.com/emojipedia-us.s3.amazonaws.com/cache/51/a3/51a3fcf2d2c44c34bd3d4a90fff477f8.png?w=25&ssl=1)](http://www.weibo.com/ttarticle/p/show?id=2309404081257721035952)\n[![](https://i1.wp.com/emojipedia-us.s3.amazonaws.com/cache/31/7a/317a88ee3fdec119bfbd5f69a6bf35b1.png?w=25&ssl=1)](https://medium.com/@gz_k/kotlin-1-1-javascript-coroutines-et-plus-ce2eb3d7004)\n[![](https://i2.wp.com/emojipedia-us.s3.amazonaws.com/cache/a4/0d/a40df75ad96b0d143df710080c710f0f.png?w=25&ssl=1)](https://blog.jetbrains.com/jp/2017/03/01/739)\n[![](https://i0.wp.com/emojipedia-us.s3.amazonaws.com/cache/f8/e1/f8e14a4d5c26dedc5b0639ca763bc03a.png?w=25&ssl=1)](http://kotlin.kr/2017/03/01/kotlin-1-dot-1.html)\n[![](https://i2.wp.com/emojipedia-us.s3.amazonaws.com/cache/80/da/80da132bc3307d3d2ac0729493eb4c26.png?w=25&ssl=1)](https://habrahabr.ru/company/JetBrains/blog/323012/)\n[![](https://i2.wp.com/emojipedia-us.s3.amazonaws.com/cache/77/3e/773e66b858a69ddbade6951fdb012949.png?w=25&ssl=1)](http://kotlin.es/2017/03/1.1.0/)\n\nToday we release Kotlin 1.1. It’s a big step forward enabling the use of Kotlin in many new scenarios, and we hope that you’ll enjoy it.\n\n![Kotlin 1.1](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2017/03/Kotlin11blogbanner1.png)\n\nOur vision for Kotlin is to enable the use of a single expressive, performant, strongly typed language across all components of a modern application. Kotlin 1.1 makes two major steps towards this goal.\n\nFirst, the _JavaScript target_ is no longer experimental, and supports all Kotlin language features, a large part of the standard library, as well as JavaScript interoperability. This allows you to migrate the browser frontend of your applications to Kotlin, while continuing to use modern JavaScript development frameworks such as React.\n\nSecond, we’re introducing support for _coroutines_. As a lightweight alternative to threads, coroutines enable much more scalable application backends, supporting massive workloads on a single JVM instance. In addition to that, coroutines are a very expressive tool for implementing asynchronous behavior, which is important for building responsive user interfaces on all platforms.\n\nBelow we describe these two changes further. In other news: we’ve added [type aliases](http://kotlinlang.org/docs/reference/whatsnew11.html#type-aliases), [bound callable references](http://kotlinlang.org/docs/reference/whatsnew11.html#bound-callable-references), [destructuring in lambdas](http://kotlinlang.org/docs/reference/whatsnew11.html#destructuring-in-lambdas) and more. See the details in our [What’s new](http://kotlinlang.org/docs/reference/whatsnew11.html) page (check out the runnable examples!).\n\n## Coroutines\n\nCoroutines in Kotlin make non-blocking asynchronous code as straightforward as plain synchronous code.\n\nAsynchronous programming is taking over the world, and the only thing that is holding us back is that non-blocking code adds considerable complexity to our systems. Kotlin now offers means to tame this complexity by making coroutines first-class citizens in the language through the single primitive: _suspending functions_. Such a function (or lambda) represents a computation that can be suspended (without blocking any threads) and resumed later.\n\nTechnically, coroutines are light-weight means of cooperative multi-tasking (very similar to [fibers](https://en.wikipedia.org/wiki/Fiber_(computer_science))). In other words, they are just _much better threads_: almost free to start and keep around, extremely cheap to suspend (suspension is for coroutines what blocking is for threads), very easy to compose and customize.\n\nWe designed coroutines for maximum flexibility: very little is fixed in the language, and very much can be done as a library. The [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) project features libraries on top of Rx, CompletableFuture, NIO, JavaFx and Swing. Similar libraries can be written for Android and JavaScript. Even many built-in constructs available in other languages can now be expressed as Kotlin libraries. This includes generators/yield from Python, channels/select from Go and async/await from C#:\n\n```kotlin\n// runs the code in the background thread pool\nfun asyncOverlay() = async(CommonPool) {\n // start two async operations\n val original = asyncLoadImage(\"original\")\n val overlay = asyncLoadImage(\"overlay\")\n // and then apply overlay to both results\n applyOverlay(original.await(), overlay.await())\n}\n\n// launches new coroutine in UI context\nlaunch(UI) {\n // wait for async overlay to complete\n val image = asyncOverlay().await()\n // and then show it in UI\n showImage(image)\n}\n```\n\nRead more in our [docs](http://kotlinlang.org/docs/reference/coroutines.html).\n\n**An important note**. With all the benefits that they bring, Kotlin coroutines are a fairly new design that needs extensive battle-testing before we can be sure it’s 100% right and complete. This is why we will release it under an “experimental” [opt-in flag](http://kotlinlang.org/docs/diagnostics/experimental-coroutines.html). We do not expect the language rules to change, but APIs may require some adjustments in Kotlin 1.2.\n\n## JavaScript support\n\nAs mentioned above, all language features in Kotlin 1.1, including coroutines, work on both JVM/Android and JavaScript. (Reflection for JavaScript is not available, but we’re looking into it.) This means that a web application can be written entirely in Kotlin, and we already have some experience doing that inside JetBrains. We will publish tutorials and other materials about this soon.\n\nKotlin for JavaScript has dynamic types to interoperate with “native” JavaScript code. To use well-known libraries through typed APIs, you can use the [ts2kt converter](http://github.com/kotlin/ts2kt) together with headers from [DefinitelyTyped](http://github.com/DefinitelyTyped/DefinitelyTyped).\n\nWe support both Node.js and the browser. The Kotlin Standard Library is available for use through `npm`.\n\nRead more in our [docs](http://kotlinlang.org/docs/reference/js-overview.html).\n\n## Tooling\n\nKotlin 1.1 is not a major release for Kotlin tooling: we prefer shipping tooling features that do not affect the language itself as soon as they are ready, so you’ve seen many such improvements in Kotlin 1.0.x versions. To highlight a few:\n\n* Kotlin plugins for all the major IDEs: IntelliJ IDEA, Android Studio, Eclipse and NetBeans\n* Incremental compilation in both IntelliJ IDEA and Gradle\n* Compiler plugins for Spring, JPA and Mockito (making classses open and generating no-arg constructors)\n* kapt for annotation processing\n* Lint support for Android projects\n* Numerous IDE intentions, inspections, quick fixes, refactorings and code completion improvements\n\nWe’ll keep working to make our tooling even better and deliver the updates in 1.1.x versions.\n\n## First year of Kotlin: Adoption and Community\n\nIn short, Kotlin is growing. We’ve seen over 160’000 people using it during the last year. OSS projects on Github grew from 2.4M to 10M lines of Kotlin code (about 4x). Our Slack community has grown from 1’400 to over 5’700 people (over 4x). Numerous meet-ups and user groups are organized by the community [around the world](http://kotlinlang.org/community/talks.html). We are seeing more and more Kotlin books and online courses published.\n\n![Kotlin GitHub Stats](https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2017/03/GitHub-Stats-1.gif)\n\nKotlin is equally strong with server-side and Android developers (roughly 50/50 divide). Spring Framework 5.0 [has introduced Kotlin support](https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0), so did [vert.x 3.4](http://vertx.io/blog/vert-x-3-4-0-beta1-release/). [Gradle](https://blog.gradle.org/kotlin-meets-gradle) and [TeamCity](https://blog.jetbrains.com/teamcity/2016/11/kotlin-configuration-scripts-an-introduction/) are using Kotlin for build scripts. More projects using Kotlin can be found at [kotlin.link](http://kotlin.link/).\n\nMany well-known companies are using Kotlin: [Pinterest](https://www.youtube.com/watch?v=mDpnc45WwlI), [Coursera](https://building.coursera.org/blog/2016/03/16/becoming-bilingual-coursera/), [Netflix](https://twitter.com/robspieldenner/status/708355228832178176), [Uber](https://www.reddit.com/r/androiddev/comments/5sihp0/2017_whos_using_kotlin/ddfmkf7/), [Square](https://github.com/square/sqldelight), [Trello](https://twitter.com/danlew42/status/809065097339564032), [Basecamp](https://m.signalvnoise.com/some-of-my-favorite-kotlin-features-that-we-use-a-lot-in-basecamp-5ac9d6cea95), amongst others. [Corda](https://github.com/corda/corda), a distributed ledger developed by a consortium of well-known banks (such as Goldman Sachs, Wells Fargo, J.P. Morgan, Deutsche Bank, UBS, HSBC, BNP Paribas, Société Générale), has [over 90% Kotlin](https://www.corda.net/2017/01/10/kotlin/) in its codebase.\n\nWe are grateful to all our users, contributors and advocates in all parts of the world. Your support is very important to us!\n\n### Organize your own Kotlin 1.1 Event\n\nKotlin 1.1 is a good reason to meet up with your local user group and friends. We have prepared some materials to help you organize such an event. On March 23 we’ll stream live sessions featuring the Kotlin team members, plus there’s an organizers pack that includes some swag and a Future Features Survey. Get more info and [register your event here](https://docs.google.com/forms/d/e/1FAIpQLSf6iXcrIpaNIqeeUJI2L6pntS5yy_iI01PbrO9gTMmX0kg5Lw/viewform).\n\n## What’s next\n\nTo make Kotlin a truly full-stack language, we are going to provide tooling and language support for compiling the same code for multiple platforms. This will facilitate sharing modules between client and server. We will keep working on improving the JavaScript tooling and library support. Among other things, incremental compilation for the JavaScript platform is in the works already. Stay tuned for 1.1.x updates.\n\nJava 9 is coming soon, and we will provide support for its new features before it ships.\n\nWe expect a lot of feedback on coroutines in the upcoming months, and improving this area of the language (in terms of both performance and functionality) is among our priorities.\n\nApart from this, our next release will be mostly focused on maintenance, performance improvements, infrastructure and bugfixing.\n\nP.S. Running on multiple platforms is a strategic direction for Kotlin. With 1.1 we can run on servers, desktops, Android devices and browsers, but in the future we are going to compile Kotlin to native code and run on many more platforms (including, for example, iOS and embedded devices). A great team here at JetBrains is working on this project, and we are expecting to show something interesting fairly soon. This does not target any particular release yet, though.\n\n## Installation instructions\n\nAs always, you can **try Kotlin online** at [try.kotlinlang.org](http://try.kotlinlang.org/).\n\n**In Maven/Gradle**: Use `1.1.0` as the version number for the compiler and the standard library. See the docs [here](http://kotlinlang.org/docs/reference/using-gradle.html).\n\n**In IntelliJ IDEA**: 2017.1 has Kotlin 1.1 bundled, in earlier versions Install or update the Kotlin plugin to version 1.1.\n\n**In Android Studio**: Install or update the plugin through _Plugin Manager_.\n\n**In Eclipse**: install the plugin using [Marketplace](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse).\n\n**The command-line compiler** can be downloaded from the [Github release page](https://github.com/JetBrains/kotlin/releases/tag/v1.1).\n\n**Compatibility**. In Kotlin 1.1 the language and the standard library are [backwards compatible (modulo bugs)](http://kotlinlang.org/docs/reference/compatibility.html): if something compiled and ran in 1.0, it will keep working in 1.1. To aid big teams that update gradually, we provide a compiler switch that disables new features. [Here](http://kotlinlang.org/docs/reference/compatibility.html#binary-compatibility-warnings) is a document covering possible pitfalls.\n\n_Have a nice Kotlin!_\n\nP.S. See discussions on [Reddit](https://www.reddit.com/r/programming/comments/5wvpv8/kotlin_11_released_with_javascript_support/) and [Hacker News](https://news.ycombinator.com/item?id=13763483)\n","author":"Roman Belov","date":"2017-03-01","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"News from KotlinTest","url":"https://discuss.kotlinlang.org/t/news-from-kotlintest/1797","body":"\nIn the last weeks [KotlinTest](https://github.com/kotlintest/kotlintest) got some new and useful features:\n\n## Testing for Exceptions\n\n```kotlin\nval exception = shouldThrow {\n // code in here that you expect to throw an IllegalAccessException\n}\nexception.message should start with \"Something went wrong\"\n```\n\n## Before and after each\n\n```kotlin\noverride fun beforeEach() {\n println(\"Test starting\")\n}\n\noverride fun afterEach() {\n println(\"Test completed\")\n}\n```\n\n\n## Test configuration\n\nEach test case can followed by a call to the `config` function.\n\nTo execute a test two times with two threads you would write:\n\n```kotlin\nclass MyTests : ShouldSpec() {\n init {\n\n should(\"return the length of the string\") {\n \"sammy\".length shouldBe 5\n \"\".length shouldBe 0\n }.config(invocations = 10, threads = 2)\n\n }\n}\n```\n\nYou can tag tests to be able run them selectively:\n\n```kotlin\n...\n}.config(tags = listOf(\"database\", \"linux\"))\n```\n\nTimeouts are configured like this:\n\n```kotlin\n...\n}.config(timeout = 2, timeoutUnit = TimeUnit.SECONDS)\n```\n\nTo ignore a test, you set `ignored` to true:\n\n```kotlin\n...\n}.config(ignored = true)\n```\n\n## Future\n\nSome more features like property based (and table driven) testing are on the roadmap.\n","author":"medium","date":"2016-06-14","type":"article","categories":["Testing","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Meets Gradle","url":"http://gradle.org/blog/kotlin-meets-gradle/","body":"\nMany readers will be familiar with JetBrains’ excellent [Kotlin](http://kotlinlang.com) programming language. It’s been under development since 2010, had its first public release in 2012, and went 1.0 GA earlier this year.\n\nWe’ve been watching Kotlin over the years, and have been increasingly impressed with what the language has to offer, as well as with its considerable uptake—particularly in the Android community.\n\nLate last year, Hans sat down with a few folks from the JetBrains team, and they wondered together: what might it look like to have a Kotlin-based approach to writing Gradle build scripts and plugins? How might it help teams—especially big ones—work faster and write better structured, more maintainable builds?\n\nThe possibilities were enticing.\n\nBecause Kotlin is a statically-typed language with deep support in both IDEA and Eclipse, it could give Gradle users proper IDE support from auto-completion to refactoring and everything in-between. And because Kotlin is rich with features like first-class functions and extension methods, it could retain and improve on the best parts of writing Gradle build scripts—including a clean, declarative syntax and the ability to craft DSLs with ease.\n\nSo we got serious about exploring these possibilities, and over the last several months we’ve had the pleasure of working closely with the Kotlin team to develop a new, Kotlin-based build language for Gradle.\n\nWe call it Gradle Script Kotlin, and Hans just delivered the first demo of it onstage at JetBrains’ Kotlin Night event in San Francisco. We’ve [released the first milestone](https://github.com/gradle/gradle-script-kotlin/releases/tag/v1.0.0-M1) towards version 1.0 of this work today, along with open-sourcing its repository at [https://github.com/gradle/gradle-script-kotlin](https://github.com/gradle/gradle-script-kotlin).\n\n[![KotlinGradleBanner](http://gradle.wpengine.netdna-cdn.com/wp-content/uploads/2016/05/KotlinGradleBanner.gif)](http://gradle.wpengine.netdna-cdn.com/wp-content/uploads/2016/05/KotlinGradleBanner.gif)\n\nSo what does it look like, and what can you do with it? At a glance, it doesn’t look _too_ different from the Gradle build scripts you know today:\n\n[![pasted image 0](http://gradle.wpengine.netdna-cdn.com/wp-content/uploads/2016/05/pasted-image-0.png)](http://gradle.wpengine.netdna-cdn.com/wp-content/uploads/2016/05/pasted-image-0.png)\n\nBut things get very interesting when you begin to explore what’s possible in the IDE. You’ll find that, suddenly, the things you usually expect from your IDE _just work_, including:\n\n* auto-completion and content assist\n* quick documentation\n* navigation to source\n* refactoring and more\n\nThe effect is dramatic, and we think it’ll make a big difference for Gradle users. Now, you might be wondering about a few things at this point—like whether existing Gradle plugins will work with Gradle Script Kotlin (yes, they will), and whether writing build scripts in Groovy is deprecated (no, it’s not). You can find complete answers to these and other questions in the [project FAQ](https://github.com/gradle/gradle-script-kotlin/wiki/Frequently-Asked-Questions). Do let us know if you have a question that’s not answered there.\n\nOf course, all this is just the beginning. We’re happy to announce that Kotlin scripting support will be available in Gradle 3.0, and we’ll be publishing more information about our roadmap soon. In the meantime, there’s no need to wait—you can try out Gradle Script Kotlin for yourself right now by [getting started with our samples](https://github.com/gradle/gradle-script-kotlin/tree/master/samples#readme).\n\nAnd we hope you do, because we’d love your feedback. We’d love to hear what you think, and how you’d like to see this new work evolve. You can file issues via the project’s [GitHub Issues](https://github.com/gradle/gradle-script-kotlin/issues) and please come chat with us in the #gradle channel of the public [Kotlin Slack](http://kotlinslackin.herokuapp.com/).\n\nI’d like to say a big thanks to my colleague Rodrigo B. de Oliveira for the last few months of working together on this project—it’s been a lot of fun! And a big thanks to the Kotlin team, in particular Ilya Chernikov and Ilya Ryzhenkov for being so responsive in providing us with everything we needed in the Kotlin compiler and Kotlin IDEA plugin. Onward!\n\n","author":"Chris Beams","date":"2016-05-18","type":"article","categories":["Kotlin","Gradle"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Видео со встречи JUG.ru с разработчиками Kotlin","url":"https://github.com/Heapy/awesome-kotlin/blob/master/app/rss/articles/%5BRU%5D%20%D0%92%D0%B8%D0%B4%D0%B5%D0%BE%20%D1%81%D0%BE%20%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8%20JUG.ru%20%D1%81%20%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%87%D0%B8%D0%BA%D0%B0%D0%BC%D0%B8%20Kotlin.md","body":"\n\n## Часть 1. Введение\nАндрей Бреслав расскажет про то, что такое Kotlin, как у него сейчас дела и т.д.\n[Андрей Бреслав — Что такое Kotlin Введение](https://www.youtube.com/watch?v=HWyd1gYMkl0)\n\n## Часть 2. К релизу и далее\nНачиная с версии 1.0, Kotlin предоставляет гарантии обратной совместимости с существующим кодом. Дмитрий Жемеров расскажет о том, что в точности они обещают на будущее, о том, как это обещание повлияло на дизайн языка, и о том, под какие направления будущего развития уже есть заготовки в версии 1.0.\n[Дмитрий Жемеров, JetBrains — Kotlin - к релизу и далее](https://www.youtube.com/watch?v=m5T0M7SnCC0)\n\n## Часть 3. Самое сложное — совместимость\n[Андрей Бреслав — Kotlin - самое сложное — совместимость](https://www.youtube.com/watch?v=LWFx4QWrTyo)\nАндрей Бреслав расскажет о том, как они боролись за прозрачную совместимость: чтобы Kotlin и Java могли дружно обитать в одном проекте. Для этого пришлось придумать немало оригинальных решений и пойти на многие компромиссы на всех уровнях: от системы типов до плагинов к билд-системам.\n\n## Часть 4. Сессия вопросов и ответов\n[Андрей Бреслав и Дмитрий Жемеров — Kotlin - сессия вопросов и ответов](https://www.youtube.com/watch?v=YOmdOTlhZa8)\nАндрей, Дмитрий и другие разработчики Kotlin с удовольствием ответят на ваши вопросы.\n\n","author":"JetBrains","date":"2016-03-04","type":"article","categories":["Kotlin","Video"],"features":["highlightjs"],"description":"","filename":"","lang":"RU","enclosure":null},{"title":"Better Android Development with Kotlin and Gradle","url":"https://www.youtube.com/watch?v=bVSeKexyzhs","body":"\n\n# v1\n\nIn this talk, Ty will walk you through setting up and using Kotlin with Gradle to streamline your workflow for Android development, both within the build tool phase and within the application itself. After a brief overview of Kotlin, we’ll dive into how it can be used with Gradle to accelerate Android Development with a consistent language.\n\n[Slides](https://speakerdeck.com/tysmith/better-android-development-with-kotlin-and-gradle-1)\n\n\n\n# v2\n\nIn this talk, Ty will walk you through using Kotlin with Gradle and Android to streamline your workflow for app development, both within the build tool phase and within the application itself. After a brief overview of Kotlin language, he'll dive into how it can be used with Gradle to accelerate Android Development with a consistent language through the entire stack. He'll provide real world examples of using Kotlin in Gradle plugins, Gradle script, and Android apps. \n\n\n\n# v3\n\nTy Smith, Uber\nIn this talk, Ty will walk you through setting up and using Kotlin with Gradle to streamline your workflow for Android development, both within the build tool phase and within the application itself, so that you can use a consistent language through the entire Android stack. After a brief overview of Kotlin, we’ll dive into how it can be used with Gradle to accelerate Android Development with a consistent language. I'll walk through a real world example of building a Gradle plugin in and scripts in Groovy, then I'll convert those into Kotlin. An open source repo of the sample will be provided to follow along.\n\n\n\n","author":"Ty Smith","date":"2016-10-03","type":"video","categories":["Kotlin","Android","Gradle"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Non-volatile vs volatile captured refs by default","url":"https://discuss.kotlinlang.org/t/non-volatile-vs-volatile-captured-refs-by-default/2122","body":"\nKotlin compiler version 1.0.x uses reference classes with `volatile` fields when local `var`s are captured by lambdas, local functions, or local classes. This results in a quite severe performance degradation on JVM backend for idiomatic Kotlin code that uses Kotlin's unique (with respect to Java) feature of capturing mutable variables. We are considering to change this implementation strategy in Kotlin 1.1 to use reference classes with non-volatile fields by default. The purpose of this thread is to gather feedback on this proposed change.\n\nThe proposed change will not affect non-concurrent code semantics, but it will make it significantly faster on JVM in many cases simply by recompilation with Kotlin 1.1. Most correct concurrent code will likewise continue to work correctly after this change and with improved performance, too. However, we can imagine some cases where existing concurrent code is working correctly with Kotlin 1.0.x as a side effect of this particular implementation strategy, but will cease to operate correctly if the proposes change is implemented in Kotlin 1.1. We cannot figure out a simple way to automatically scan Kotlin open source codebase to see how prevalent those cases in real Kotlin code are, so we need your help in finding those cases to judge the extent of this proposed change. Real-world examples of such code are highly appreciated.\n\n# Links\n\n* The corresponding performance problem is tracked as an issue [https://youtrack.jetbrains.com/issue/KT-14746](https://youtrack.jetbrains.com/issue/KT-14746) It provides some low-level implementation details of what bytecode is generated by Kotlin 1.0.x and how references are implemented.\n\n* Some micro-benchmarking results are presented at [http://www.slideshare.net/intelliyole/kotlin-bytecode-generation-and-runtime-performance](http://www.slideshare.net/intelliyole/kotlin-bytecode-generation-and-runtime-performance) (slide #27) Note, however, that it is does not really show the gravity and the extent of the problem in real-life use-cases.\n\n# FAQ\n\n## What is volatile?\n\nThe `volatile` is a JVM modifier that imbues a variable with a special semantics with respect to Java Memory Model (JMM). The semantics for volatile are specified in Chapter 17 of Java Language Specification: [https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html](https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html) **TL;DR**: reads and writes of `volatile` variables are considered to be _synchronisation_ actions for concurrent code, providing an alternative inter-thread synchronisation mechanism for writing _lock-free_ code. Volatile variables are optional for correct concurrent code, in the sense that there are many other synchronisation primitives like starting/joining threads, using locks, using futures and various other xxxConcurrent and xxxAtomic classes.\n\n## What are performance problems with volatile / why not everything is volatile?\n\nThe possible behaviours of the code that is reading/writing volatile variables are quite constrained by specification, so compiler cannot do many of the typical optimisations that modern compilers usually do. For example, compiler is not allowed to optimize away redundant reads from volatile variables and replace them with a read into register, which has cascading effect on many other code optimisations. Unfortunately, it also affects optimisation of other code around reads and write of volatile variable. Even a single volatile read/write in a piece of a typical code can make a lot of it much less optimised. This is the reason why modern languages choose to treat all variables as non-volatile by default. This enables full scope of code optimisation, unless the programmer who is writing concurrent code explicitly wants to use _lock-free synchronisation_ in their code and marks the corresponding variables as `volatile`. Kotlin follows the same strategy with respect to class variables and provides `@Volatile` annotation in `kotlin.jvm` package in order to make class variables volatile.\n\n## Why captured mutable variables are important?\n\nCaptured mutable variables might seem a niche feature of Kotlin at a first glance, since they are not present in Java. Moreover, modern collections / sequence-processing libraries strongly advocate against any kind of mutable state and provide a rich set of filter/map/etc primitives to enable writing even complex logic without any kind of mutable state. Kotlin stdlib is a good example of such a rich library. Moreover, writing your code without mutable variables makes it easy to parallelise. For example, with Java Streams parallelisation is as simple as adding `.parallel()` invocation to your pipeline, unless you are mutating any state, that is.\n\nHowever, Kotlin's powerful lambdas enable user-defined control constructs that work similarly to the ones built into the language. So, Kotlin can have fewer built-in control constructs and define things like Java's _synchronised_ and _try-with-resources_ as a library instead. This ability relies on capturing local mutable state.\n\nMoreover, when writing complex _single threaded_ (classical) data-processing algorithms one often needs to share some mutable state between several functions. In Java it typically boils down to “Doer” class anti-pattern, e.g. in order to implement a hypothetical `compute()` function, you create `Computer` class, in order to implement some `graphSearch` function you create `GraphSearcher` class, etc. It is all a boilerplate code to work around Java limitations. Kotlin's support of local functions lets us get rid of such a boiler plate and write our algorithms directly and _naturally_.\n\n## Work around for performance in Kotlin 1.0.x\n\nWhat do you do if you have exactly this kind of code where you'd like to use captured mutable state to apply some local functions or lambdas as a part of your algorithm, for example. How do you regain Java speed of this code on JVM? The solution in Kotlin 1.0.x is to write this code in Java style, e.g. ditch idiomatic Kotlin and write the Java boilerplate you typically do to work with mutable state in Java. For example, if you have the following code snippet:\n\n```kotlin\nvar myVariable = initialValue\n\n// here is the code that uses myVariable in lambdas and local functions\n```\n\nyou can use the following boilerplate code to regain runtime performance in Kotlin 1.0.x at a cost of extra class file. If you ignore the boilerplate it even looks similar to the original code. Kotlin is such a nice language that even boilerplate code in Kotlin is shorter than in Java :)\n\n```kotlin\nwith (object {\n var myVariable = initialValue\n}) {\n // here is the code that uses myVariable in lambdas and local functions\n}\n```\n\nHowever, you should not _actually_ write such code. If you really need that performance, then you should extract your variables into some named class. It is going to require _more_ code, but the resulting code will be easier to read and understand.\n\n","author":"Roman Elizarov","date":"2016-11-28","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"UI Testing: separating Assertions from Actions with Kotlin DSL","url":"https://artemzin.com/blog/ui-testing-separating-assertions-from-actions-with-kotlin-dsl/","body":"\nHello, dear reader!\n\nRecently Jake Wharton did a talk [\"Instrumentation Testing Robots\"](https://realm.io/news/kau-jake-wharton-testing-robots/) \uD83D\uDCFA.\n\nThe pattern itself is not a new concept, **but** combining it with [Kotlin DSL](https://kotlinlang.org/docs/reference/type-safe-builders.html) is pretty nice! So we decided to try it for our [Juno app](https://play.google.com/store/apps/details?id=com.gojuno.rider) which is fully written in Kotlin, including Unit, Integration and Functional tests.\n\nWhat we found is that mixing Actions and Assertions inside \"Robots\" (we call them Screens) doesn't look great, both for tests readability and \"Robot\" maintenance \uD83E\uDD16 (same is true for regular Screen abstractions).\n\n> Though I used mixed variant for years... (sigh). For some reason, only seeing screen abstraction as a Kotlin DSL finally clicked that we need to divide assertions from actions.\n\n#### Before: mixed Actions and Assertions \uD83D\uDE3F\n\n```kotlin\n// We actually use Spek but unfortunately I can't say\n// that it works great for instrumentation tests yet...\n@Test fun loginAndPasswordAreEntered() {\n loginScreen {\n\n login(\"artem_zin\")\n password(\"*****\")\n\n loginButtonActivated()\n noLoginWarnings()\n noPasswordWarnings()\n }\n}\n```\n\n#### After: Assertions are separated from Actions \uD83D\uDE38\n\n```kotlin\n@Test fun loginAndPasswordAreEntered() {\n loginScreen {\n\n login(\"artem_zin\")\n password(\"*****\")\n\n assert {\n loginButtonActivated()\n noLoginWarnings()\n noPasswordWarnings()\n }\n }\n}\n```\n\nNow that's a clear separation of actions and assertions, right? Same is true for internal structure of `LoginScreen` class:\n\n```kotlin\nfun loginScreen(func: LoginScreen.() -> Unit) = LoginScreen().apply { func() }\n\nclass LoginScreen {\n\n fun login(login: String) = enterText(R.id.login, email)\n fun password(password: String) = enterText(R.id.password, password)\n fun assert(func: Assert.() -> Unit) = Assert().apply { func() }\n\n // Previously all these assertions \n // were on the same level in the LoginScreen class as actions.\n class Assert {\n fun loginButtonActivated() = ...\n fun noLoginWarnings() = ...\n fun noPasswordWarnings() = ...\n }\n}\n```\n\n> Write tests and take care!\n\n","author":"Artem Zinnatullin","date":"2016-07-27","type":"article","categories":["Kotlin","Testing"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Fun with Kotlin","url":"https://vimeo.com/151846078","body":"\n\n[Fun with Kotlin](https://vimeo.com/151846078)\n\n","author":"Eder Bastos","date":"2016-01-14","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin - Ready for Production","url":"https://vimeo.com/181814363","body":"\n\n\nKotlin - Ready for Production : Hadi Hariri from JavaZone on Vimeo.\n\n[Transcript](https://realm.io/news/gotocph-hadi-hariri-kotlin-ready-for-production/)\n\n","author":"Hadi Hariri","date":"2016-09-07","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1 Release Candidate is Here","url":"https://blog.jetbrains.com/kotlin/2017/02/kotlin-1-1-release-candidate-is-here/","body":"\nAs of today, Kotlin 1.1 has finally reached the release candidate stage. This means that most of our development work is done, we’re happy with the results, and we’ll soon publish them as a final Kotlin 1.1 release. We’ve done a lot of testing for this release internally, but the real world is always more varied than any test environment, so we need your help. Please try this build, and let us know about your experience!\n\n![11RC-01][]\n\n\nThe only new feature in the release candidate is the `takeUnless` function – a counterpart of [takeIf][] (added earlier in 1.1) but with an inverted condition. As for bugfixes, there’s much more, and the [changelog][] gives you a complete list. Among other things, we’ve fixed several performance problems in the IDE – both long-standing sore points and recent regressions.\n\n## Migration Notes ##\n\nAs we [noted][] earlier, all binaries produced by pre-release versions are outlawed by the compiler: you’re now **required to recompile** everything that was compiled by 1.1‑M0x and Beta’s. All the code from 1.0.x is, of course, perfectly fine without recompilation.\n\nUp until now, you could run the Kotlin compiler under any version of Java starting with Java 6, but this is about to change – starting with one of the first 1.1.x updates, the compiler will only run under Java 8 or 9. To prepare you for the migration, the compiler now emits a warning if you run it under Java 6 or 7. Note that this only affects the build environment; **the compiled code is still compatible with Java 6 by default**, and we have no plans to remove the support for that.\n\nThe `.javaClass` extension property is now deprecated. As a replacement, please use `::class.java`. The IDE offers a quickfix to update usages, both individually and across the entire project.\n\nTo reduce the size of the JavaScript standard library, we’ve deprecated a lot of helper functions in the `kotlin.dom` and `kotlin.dom.build` packages, and we’re going to remove them in a future update.\n\n## How to try it ##\n\n**In Maven/Gradle:** Add `http://dl.bintray.com/kotlin/kotlin-eap-1.1` as a repository for the build script and your projects; use `1.1.0-rc-91` as the version number for the compiler and the standard library.\n\n**In IntelliJ IDEA:** Go to *Tools → Kotlin → Configure Kotlin Plugin Updates*, then select “Early Access Preview 1.1” in the *Update channel* drop-down list, then press *Check for updates*.\n\n**In Eclipse**: install the plugin with the following update site\n`https://dl.bintray.com/jetbrains/kotlin/eclipse-plugin/0.8.0`\n\n**The command-line compiler** can be downloaded from the [Github release page][].\n\n**On [try.kotlinlang.org][]**.\n\nLet’s Kotlin!\n\n\n[11RC-01]: https://d3nmt5vlzunoa1.cloudfront.net/kotlin/files/2017/02/11RC-01.png\n[takeIf]: https://kotlinlang.org/docs/reference/whatsnew11.html#takeif-and-also\n[changelog]: https://github.com/JetBrains/kotlin/blob/1.1-rc/ChangeLog.md\n[noted]: https://blog.jetbrains.com/kotlin/2017/01/kotlin-1-1-beta-is-here/\n[Github release page]: https://github.com/JetBrains/kotlin/releases/tag/v1.1-rc\n[try.kotlinlang.org]: http://try.kotlinlang.org/\n","author":"Mikhail Glukhikh","date":"2017-02-17","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Christina Lee: Kotlin in Production","url":"https://www.youtube.com/watch?v=xRDqDe4rxkM","body":"\n# v1\n\nWhile in New York for Droidcon NYC, Huyen hangs out with Christina Lee, Pinterest Android engineer and cross-country runner, to talk about bringing Kotlin into your production apps.\n\n\n\n# v2\n\nChristina Lee, Pinterest\nIt is hard to argue that Kotlin is not an amazing language. What is easy to argue is that there are many unknowns about its performance in the wild and at scale, which makes it hard to make an informed decision about incorporating it into your app. Fortunately for you, we went there and have lived to tell the tale. After more than a year of maintaining a pure Kotlin app at Highlight, and more recently helping Pinterest ramp up Kotlin in Android, we've learned much about the ramifications of moving away from Java. Come learn from our mistakes and successes as we cover the highs, and lows, of using Kotlin in the wild!\n\n\n\n","author":"Android Dialogs","date":"2016-10-18","type":"video","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Generating Kotlin Code for Better Refactorings, Tests, and IDE Support","url":"https://docs.google.com/presentation/d/1pgzNnA4R3LU4hPnx0KTvQ0NFj23rPyq-ROr8kOiaxlM/edit#slide=id.p","body":"\n[Slides on Google Slides](https://docs.google.com/presentation/d/1pgzNnA4R3LU4hPnx0KTvQ0NFj23rPyq-ROr8kOiaxlM/edit#slide=id.p)\n\n","author":"Eugene Petrenko","date":"2016-09-20","type":"slides","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin - 2 Years On","url":"https://yobriefca.se/blog/2016/02/24/kotlin-2-years-on/","body":"\nI [first played](https://yobriefca.se/blog/2012/07/14/kotlin-heres-what-i-think-for-now/) with Kotlin back in 2012, I've written some Android apps with and without it and generally played around with it. Since the [release of Kotlin 1.0](http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmatic-language-for-jvm-and-android/) a few days ago I've decided to jump back into it and see if my original views still hold up.\n\n> Herein lies opinion of the personal kind. Proceed with an open mind.\n\nScala is my day job, not only Scala but **legacy/old** Scala. Not only that but **a lot** of legacy/old Scala. Worse still not only a lot of legacy/old Scala but a lot of **other peoples** legacy/old Scala. Thanks to the feature rich and impressively flexible nature of Scala this means there is a lot of sharp edges, unpredictability and a fresh arduous learning curve for each functional area. It can seem like a language designed by [Atë](https://en.wikipedia.org/wiki/At%C3%AB) at times.\n\nJava is no better of course, it just resides at the other end of a spectrum, with its anaemic yet rigid feature set and almost pointless type system it's no wonder you see so many over-engineered and baklava-class layered solutions. Yeah Java 8 has improved the language a fair bit but the sacrifices made for backwards compatibility has meant those changes don't often go far enough.\n\nBoth Scala and Java require a lot of work to simplify so there has to be a middle ground and I (still) think that middle ground is Kotlin.\n\nThink of Kotlin as C# for the JVM, Scala the Good Parts, Java++ or simply a decent general purpose language that won't require the blood of your first born. It's created by Jetbrains, it's about 5ish years old and just gone version 1.0. It is used extensively on Jetbrains products, being hailed as \"Swift for Android\" and works seamlessly within a mixed code base. It offers features similar to C# Extension methods, Scala implicits, Scala case classes, multiple inheritance and solid collection functionality like LINQ. It doesn't just ape Scala and C# features but introduces relatively original concepts like [delegated properties](http://kotlinlang.org/docs/reference/delegated-properties.html), [class delegation](https://kotlinlang.org/docs/reference/delegation.html#class-delegation) and [typecasting](https://kotlinlang.org/docs/reference/typecasts.html).\n\nI'd also proffer that it has an easier transition from Java to Kotlin than it is for Scala though I have no evidence for this other than my own experience of all 3 languages (including leading mixed skill teams in Scala and Java).\n\nYou could ask \"but why not one of the other many languages available on the JVM?\" and that would be fair. Many JVM languages haven't seen a great deal of traction or remain relatively niche but I think Kotlin is much better placed. It's more \"general purpose\" than a lot of the alt languages which means it will map better to current practises. It's closer to Java and/or Scala than other languages, it strikes the right balance around the type system with features like type inference and enhanced generics and it doesn't hurt that Jetbrains; a major player in the JVM world; is heavily invested in Kotlins future.\n\nIn the two years since I started playing with Kotlin it has aged well. It resisted adding a plethora of features for the sake of it and instead created a core syntax and feature set that allows developers enough wiggle room for being creative without turning them into Wizards of Arcane DSLs. This is a sweet spot for me when it comes to building and supporting a service over many years as it avoids the unnecessary pain that comes from the extreme ends of spectrum that Java and Scala tend to reside. Of course this doesn't mean it's perfect, nothing is. You're still adding another language to a project and taking on the associated baggage that comes with it like tooling differences and additional upskilling. Its not suddenly going to make your organisation move the JVM if they aren't already there. It's also not going to fix all your problems - bad architecture will remain bad architecture and bad patterns will remain bad patterns. However, with that said, **I believe Kotlin will reduce enough of the friction of general software development and maintenance on the JVM to make it worth the investment**.\n\n","author":"James Hughes","date":"2016-02-24","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Future of Kotlin - How agile can language development be?","url":"https://www.slideshare.net/abreslav/future-of-kotlin-how-agile-can-language-development-be","body":"\n\n","author":"Andrey Breslav","date":"2017-04-22","type":"slides","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Solutions to multiple inheritance in Kotlin","url":"https://sites.google.com/a/athaydes.com/renato-athaydes/posts/solutionstomultipleinheritanceinkotlin","body":"\nI have recently come across a little problem that recurs from time to time as I write new code.\n\nI had a base class with some really useful methods that I wanted to make another class extend, but the ditto class already extended some other, equally useful, base class.\n\nIf this were Java, I would just add a field to the class, using [composition rather than inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance) and be done with it, even if that felt a little clunky, after all that's the best you can do in Java.\n\nHowever, these days I'm using [Kotlin](https://kotlinlang.org/) more often than not. Moving on with the times, I guess!\n\nAnyway, Kotlin has a really interesting feature called [class delegation](https://kotlinlang.org/docs/reference/delegation.html), which allows you to implement composition in a much nicer way than in Java. I was already familiar with this kind of thing from using the [Groovy @Delegate](http://docs.groovy-lang.org/latest/html/gapi/groovy/lang/Delegate.html) AST in the past, so I decided to give it a go.\n\nBefore we proceed, I must note that because classes can have state and initialization logic (including side-effects), Kotlin does not allow true [multiple inheritance](https://en.wikipedia.org/wiki/Multiple_inheritance) as that could [cause havoc](https://blog.jetbrains.com/kotlin/2011/08/multiple-inheritance-part-2-possible-directions/) in slightly more complex class hierarchies (it does allow declaring properties and implementing methods in interfaces, though, as that's free of the subtle problems you could encounter with a more permissive approach)... so we will have to do something similar to Java, but with much appreciated help from the language!\n\nHere's how it works. Imagine you have two different classes you want to mix-in (ie. inherit from) to your type. As long as you have interfaces for those types, it's fairly simple:\n\n```kotlin\n interface CanFly { \n fun fly() \n } \n\n interface CanWalk { \n fun walk() \n } \n```\n\nThe concrete classes:\n\n```kotlin \n class Flyer : CanFly { \n override fun fly() = println(\"Flying!\") \n } \n\n class Walker : CanWalk { \n override fun walk() = println(\"Walking...\") \n } \n```\n\nNow, we want a type that has both the ability to walk and fly! In other words, we want a `Pony` :)\n\n```kotlin \n class Pony(flyer: CanFly, walker: CanWalk) : \n CanFly by flyer, \n CanWalk by walker \n```\n\nAnd to actually make a Pony:\n\n```kotlin \n val pony = Pony(Flyer(), Walker()) \n```\n\nIf the type we're interested in does not implement a useful interface, we can use a simple adapter that implements the interface we're interested in to achieve similar results.\n\nFor example, if `Walker` (the concrete class) did not implement `CanWalk`, we could create a `CanWalkAdapter` like this:\n\n```kotlin \n class CanWalkAdapter(private val walkFun: () -> Unit) : CanWalk { \n override fun walk() = walkFun() \n } \n```\n\nNotice that only the (non-default) interface methods need to be manually overridden. The `Pony` class itself would remain the same, and to get our `Pony` in this situation would not be too hard:\n\n```kotlin \n val pony = Pony(Flyer(), CanWalkAdapter { Walker().walk() }) \n```\n\nThis is just a silly example, so to show how this technique can actually be useful, let's imagine we have a class that already _\"burned\"_ its only chance at inheriting from a base class... and that we want to add caching to it!\n\nYou might already have a class that implements generic caching, and you would certainly want to re-use it. You couldn't mix-in an interface because interfaces, as we saw above, cannot have state, and without state you'll have trouble implementing a cache!\n\nSo, to solve this problem, let's try to use class delegates, as in the silly Pony example above.\n\nFirst, here's our class that will require a cache:\n\n```kotlin \n abstract class BaseType \n\n // the super-class is already taken class MyType : BaseType() { \n\n fun someFunctionThatCanBeCached(input: Int): String { \n // some complicated logic \n return input.toString() \n } \n } \n```\n\nA really simple cache interface/implementation:\n\n```kotlin \n interface Cache { \n fun get(input: K, create: (K) -> V): V \n } \n\n class MapCache : Cache { \n\n val map = mutableMapOf() \n\n override fun get(input: K, create: (K) -> V): V = \n map.getOrPut(input) { create(input) } \n } \n```\n\nAs we saw above, even if the cache-implementation class did not implement an interface (which we need for class delegation), we could've used an adapter to solve that.\n\nAnd finally, the modified `MyType` implementation that delegates caching to some `Cache` implementation:\n\n```kotlin \n class MyType(cache: Cache) : \n BaseType(), Cache by cache { \n\n fun someFunctionThatCanBeCached(input: Int): String { \n return get(input) { \n // some complicated logic \n println(\"Running complicated logic\") \n input.toString() \n } \n } \n } \n```\n\nWe can now run this code to make sure the cache is working:\n\n```kotlin \n fun main(args: Array) { \n val myType = MyType(MapCache()) \n\n println(myType.someFunctionThatCanBeCached(3)) \n println(myType.someFunctionThatCanBeCached(3)) \n\n } \n```\n\nRunning it prints the following:\n\n```\nRunning complicated logic\n3\n3\n```\n\nAs expected, the \"complicated logic\" only ran the first time.\n\nNow `MyType` has a cache, and can also be used anywhere a cache is required because with minimal effort, it implements the `Cache` interface (which in the real world might have quite a few more methods than this, so would be cumbersome to implement the Java-way).\n\nThis is a simple, but quite useful way to re-use functionality in Kotlin. And one more small way in which using Kotlin can improve your productivity and code quality at the same time.\n\n","author":"Renato Athaydes","date":"2016-11-30","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin: Easily storing a list in SharedPreferences with Custom Accessors","url":"http://blog.dennislysenko.com/2016/01/22/kotlin-easily-storing-a-list-in-sharedpreferences-with-custom-accessors/","body":"\nSharedPreferences is at its core a simple tool with a deceptively verbose interface that weighs heavily on developer productivity. Kotlin on its own will not necessarily make Java-interfacing code pretty and concise, but you can apply a few particular concepts to create an elegant, downright easy-to-use solution to a common use-case:\n\n**Storing a list of strings that will persist across app sessions.**\n\nYou can write code as if you have a regular old stored List property, with the additional benefit that it is always in sync with SharedPreferences (*):\n\n```kotlin\n// Adding to a list\nif (syncingSongIds.indexOf(song.id) == -1) {\n syncingSongIds += song.id\n}\n\n// Iterate through a list and do something with each element\nsyncingSongIds.forEach { id ->\n stopSyncing(id)\n}\n\n// Best of all: subtracting from a list\nval intent = Intent(DONE_SYNCING)\nintent.putExtra(\"song\", song)\nsendBroadcast(intent) // send a broadcast that we're done syncing\n\nsyncingSongIds -= song.id // and remove the song id from the persisted list of syncing songs\n```\n\nIf you’re interested, read on.\n\nI’m assuming you’re doing this all inside an object or class with access to a `context` property.\n\nFirst of all, let’s set up easy access to the SharedPreferences file we’ll be reading/writing:\n\n```kotlin\nval sharedPreferences: SharedPreferences by lazy {\n // Replace with your code for accessing shared preferences\n // e.g. context.getSharedPreferences(SHARED_PREFERENCES_FILENAME, Context.MODE_PRIVATE)\n}\n```\n\nFor the uninitiated, the beauty of lazy properties (`by lazy`) is that they are initialized when you first access the property (i.e. when you first type `sharedPreferences`, it will call `context.getSharedPreferences(...)`) and stored from then on, so in this case, you will only ever call `context.getSharedPreferences(...)` once in the lifetime of your object.\n\n*Skip this paragraph if you already know what a property without a backing field is*. In Java, instance variables are conventionally stored properties. In Kotlin, we get the option to provide completely custom accessors for a property without having any storage for the property. That means we can have a property called `count: Float` on a class `Counter` where the property is never actually **stored** on the Counter class. It’s very useful in instances where you want to have a property that wraps data stored somewhere else (database, server) without having to copy that data into the class containing the property. So the count property on Counter might actually be stored in (i.e., “backed by”) a file on disk: every time you increment the counter, it writes directly to the file on disk, and every time you retrieve the counter’s value, it reads directly from the file on disk. *While this particular example out of context is not a great idea as it incurs tons of I/O overhead, I feel it effectively illustrates the concept of a non-stored property*.\n\nWe are going to create a property that reads directly from, and writes directly to, SharedPreferences, using Kotlin’s syntax for custom accessors:\n\n```kotlin\nvar syncingSongIds: List\n get() {\n val raw = sharedPreferences.getString(\"syncing_song_ids\", null) ?: return emptyList()\n return raw.split(\",\")\n }\n set(value) {\n sharedPreferences.edit().putString(\"syncing_song_idslue.joinToString(\",\")).apply()\n }\n```\n\nThat’s actually all you need to do for really simple strings that are guaranteed not to have commas in them.\n\n**NB: This will only work for very simple strings. If you want to extend this functionality to be more powerful and accept any string or object type**, try using Google GSON or another JSON serialization library (JSONObject from the Android SDK is perfectly workable, if quirky) and replacing `raw.split(\",\")` and `value.joinToString(\",\")` with a JSON -> Object, and Object -> JSON conversion respectively.\n\n**NB: Because we call `apply()` in the setter rather than `commit`, this code is relatively safe to call on the main thread but it does NOT have immediate consistency**. That is, if you call `syncingSongIds += \"asdf\"; print(syncingSongIds)` it may not include “asdf” in the printout. **To fix this, change `apply()` to `commit()`, but beware of incurring additional overhead** as the setter now has to write to disk synchronously every time it is called. It is your decision as to whether or not to call the setter on the main thread; I think it is relatively safe when done sparingly, but I would certainly keep an eye on that particular setter and make sure it doesn’t adversely impact performance in your app noticeably.\n\n\\* I’m not making any synchronicity guarantees–maybe as a part two, but ultimately if your code is not thread-safe, you should still modify and test these code snippets to fit your synchronicity needs.\n\n","author":"Dennis Lysenko","date":"2016-02-22","type":"article","categories":["Android","Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Classes in Kotlin: More power with less effort","url":"http://antonioleiva.com/classes-kotlin/","body":"","author":"Antonio Leiva","date":"2016-12-07","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"How we made Basecamp 3’s Android app 100% Kotlin","url":"https://m.signalvnoise.com/how-we-made-basecamp-3s-android-app-100-kotlin-35e4e1c0ef12","body":"\n![1_OQsP3e0v1JDMPihSMl2DSQ.png][]\nMade with ❤️ in Chicago.\n\nWe started our Kotlin journey a year ago based on two hunches: that it would 1) make a huge difference in programmer happiness and 2) wildly improve our work quality and speed.\n\nI’m happy to report that our hunches were right! As of this week, Basecamp 3’s Android app is written in 100% Kotlin. \uD83C\uDF89\n\nThat puts us in a unique position to share tips from the experience of going from all Java to all Kotlin. How do you get started? What should you look out for? What are the best ways to keep learning Kotlin?\n\nRead on!\n\n## \uD83E\uDD13 Wrap your head around the basics\n\nFirst thing’s first — take some time to get acclimated with the the language. There are free resources galore, but here are a few I’d recommend:\n\n * [Jake Wharton’s talk about Kotlin for Android][Jake Wharton_s talk about Kotlin for Android]. This was the lightbulb moment for me. After two watches, I really started to get it.\n * [Some of my favorite Kotlin features][]. I wrote this a few months after we started with Kotlin. I specifically wrote it to be basic and straightforward so it’d be easy for beginners (which I was at the time!)\n * [The Kotlin docs][]. When people tell me to read the docs, I often wince. But the Kotlin docs are legit, and are an excellent way to get acclimated.\n\n## \uD83D\uDC22 Start slow but make it real\n\nWriting your first bit of Kotlin is usually the hardest part of getting started.\n\nTo alleviate the pressure, people will often suggest you start with tests or perhaps a Gradle plugin. And while that’s extremely sound advice, it doesn’t work for me. It’s too boring and obscure to get excited about.\n\nI propose something different — write real production code.\n\nThis is important because 1) it’s something you can see working in your app right away and 2) it’s more fun! That feeling of accomplishment and seeing something work shouldn’t be discounted — it builds your confidence and keeps you motivated.\n\nOf course I don’t recommend converting a giant class all at once on your first go. Instead try converting a utility or helper *method.* Take a single method from one of your util classes and rewrite it in Kotlin.\n\nDone! You now have your first bit of production ready Kotlin.\n\n## \uD83D\uDE35 Don’t try to learn the whole language at once\n\nKotlin has *a lot* of great stuff in it — so much that you might be tempted to use it all right away.\n\nAnd while that can work, I wouldn’t recommend it. Instead find a few key concepts that click in *your* brain (not what others tell you are the best parts of the language), and practice using those to their fullest.\n\nWhen I got started, three areas clicked for me: [flow control][] (`when/if/for`), [extension functions][] (add functionality to any class you want), and [null safety][] (in particular the use of `let`). Focusing on just those few concepts helped me get started without feeling overwhelmed.\n\nDon’t be afraid to start small. You need space in your brain not only to pick up new things, but to let them stick. You’re already going to be dealing with basic syntactical differences — if you try to cram all the goodness all at once, something is bound to get overwritten in your brain.\n\n## \uD83D\uDD00 Learn from the auto converter\n\nJetBrains has done a solid job with their Kotlin plugin and its ability to auto convert Java to Kotlin. It can get your class 60–70% of the way there, leaving you with some tuning and idiomatic/stylistic things to take care of.\n\nThere are two great ways to learn from this:\n\n1. Auto convert the class, but keep the Java class handy. Put them side by side, and see how the Kotlin compares. You’ll pick up a ton by just seeing how the auto converter chose to implement the Java in Kotlin.\n2. Auto convert the class, but don’t leave it in that state — while the 60% version will run, that last 40% is what makes the difference between OK code and great code. Attack everything for clarity and conciseness and look for ways to follow [Kotlin idioms][] that the auto converter couldn’t figure out.\n\n## \uD83E\uDD14 Question all your Java habits\n\nAs you begin writing Kotlin, the sad reality is that you’ll probably have some bad Java habits you’ll need to break.\n\nI found myself writing terrible `if/else` blocks in cases where a `when` would be so much better. I was writing null checks around objects when a simple `object?.let{}` would’ve been better. And much more.\n\nYou may also have built up some strong ¯\\\\\\_(ツ)\\_/¯ attitudes toward ugly code blocks. Because Java is so verbose, over time you may have begun to accept an occasional ugly code block as “well, that’s Java”.\n\nWriting in Kotlin will help you see through those, but you will need to let go of the idea that ugly code is OK. Sure there will be times when ugly code may be situationally necessary, but you won’t be able to blame Java’s ceremony any more.\n\nSo regularly question whether you are doing something the “Kotlin way”. When you see code that feels long or complicated, pause and take another look at it. Over time you’ll develop new, better habits that will overwrite your Java ones.\n\n## \uD83C\uDFD5️\uD83D\uDCA8 Leave the campsite cleaner than you found it (no new Java ever)\n\nA good way to keep your code heading in the right direction is to tidy up small bits of Java as you pass by. As the saying goes, leave the campsite cleaner than you found it.\n\nA lot of times when building something new, you’ll incidentally need to make a small change to an existing Java class — add an attribute, change a type, etc. These are often small classes like a model or utility class.\n\nConvert them! Don’t be lazy and leave them be. This incremental, slow approach over time will save you and your team much frustration in the long run.\n\n## ❄️ Use cool downs for Kotlin\n\nA great time to work on Kotlin conversions is when you’re cooling down off a big release.\n\nOften we’ll do our normal two week cycle, release a big feature, and then take a few days to watch for stability and customer issues.\n\nThose couple days aren’t going to be enough time to get into something big, so it’s a great time to convert some classes to Kotlin. Over time you’ll get faster at this and be able to knock out a few classes per day.\n\n## \uD83D\uDC74\uD83C\uDFFB Curb your enthusiasms\n\nWhen you start to feel comfortable with Kotlin, you might get a little…excited. That’s a good thing! That energy and enthusiasm keeps you motivated and learning.\n\nBut it’s also easy to go overboard. I certainly did.\n\nI‘d collapse whatever I could into single-expression functions to save lines, only to realize I was giving up clarity. I’d use too many `when` blocks, even in cases where a simple `if/else` would’ve been sufficient and clearer. I’d write extension functions galore, then realize I was creating more cognitive overhead than I was saving.\n\nIt’s wonderful to be enthusiastic and use all the tools that Kotlin gives you. But try to keep your cool (unlike me) and make sure you’re using language features for the right reasons.\n\n## \uD83D\uDCB8 Don’t forget about your customers\n\nWhile seeing more and more Kotlin makes your life much better, you need to keep one very important (obvious?) thing in mind: your customers don’t care.\n\nI fully support the argument that programmer happiness leads to great code and ultimately a better product. It’s crucially important.\n\nBut as with all good things, you need to find the right balance. Converting all your Java to Kotlin might be a fun goal for you, but meanwhile your customers might be struggling with a nagging bug.\n\nThe great thing is that those two things aren’t mutually exclusive. Grab those bugs and squash them with Kotlin — it’s a win-win! (If we’re being honest, Java probably caused the bug in the first place anyway).\n\n## \uD83D\uDC6F Don’t go it alone\n\nDepending on your company makeup, this might be easier said than done. But if you can, find a Kotlin buddy!\n\nThere is no question that I’m more proficient at Kotlin because of my buddy [Jay][]. We regularly share ideas, review each other’s Kotlin, and poke fun at [Jamie][], our designer.\n\nSometimes that stuff happens in informal chats, but the by far the most valuable place to learn is in pull requests. You can let your code speak for itself, and the feedback can do the same. When it comes to learning Kotlin (or any new language really), this is absolutely crucial.\n\nAlright, you made it! I know that’s quite a bit to chew on — maybe some obvious, maybe some not. But I hope it helps get you on the right path to joining us in Kotlinland!\n\n*If this article was helpful to you, please do hit the* \uD83D\uDC9A *button below. Thanks!*\n\n*We’re hard at work making the* [*Basecamp 3 Android app*][Basecamp 3 Android app] *better every day (in Kotlin, of course). Please check it out!*\n\n[1_OQsP3e0v1JDMPihSMl2DSQ.png]: https://cdn-images-1.medium.com/max/800/1*OQsP3e0v1JDMPihSMl2DSQ.png\n[Jake Wharton_s talk about Kotlin for Android]: https://www.youtube.com/watch?v=A2LukgT2mKc\n[Some of my favorite Kotlin features]: https://m.signalvnoise.com/some-of-my-favorite-kotlin-features-that-we-use-a-lot-in-basecamp-5ac9d6cea95\n[The Kotlin docs]: https://kotlinlang.org/docs/reference/basic-syntax.html\n[flow control]: https://kotlinlang.org/docs/reference/control-flow.html\n[extension functions]: https://kotlinlang.org/docs/reference/extensions.html\n[null safety]: https://kotlinlang.org/docs/reference/null-safety.html\n[Kotlin idioms]: https://kotlinlang.org/docs/reference/idioms.html\n[Jay]: https://twitter.com/jayohms\n[Jamie]: https://twitter.com/asianmack\n[Basecamp 3 Android app]: https://play.google.com/store/apps/details?id=com.basecamp.bc3\n","author":"Dan Kim","date":"2017-04-29","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Testing in Kotlin","url":"http://www.51zero.com/blog/testing-in-kotlin","body":"\nFollowing on from my recent article on Kotlin for Scala developers, in this blog I’ll introduce how you can use the [KotlinTest](https://github.com/kotlintest/kotlintest) framework to write unit tests in Kotlin, which is a great way to begin exploring Kotlin.\n\nKotlinTest is based on [ScalaTest](http://www.scalatest.org/) (a superb jUnit like test framework created by Bill Venners) and offers the same choice of testing styles as well as many assertions and helpers for matching through the use of a light DSL.\n\nTo use KotlinTest first add the dependencies to your build. We’ll assume you’re using gradle (but obviously Maven is fine too).\n\n```kotlin\ncompile 'io.kotlintest:kotlintest:1.1.1'\n```\n\nThen we can create a test. Each test must extend from one of the spec classes. Each spec class offers a different way of laying out your tests. Some are very similar and similar to jTest’s @Test annotation, and some are more complicated offering BDD style descriptions.\n\n### Testing Styles\n\nLets give an example of the FlatSpec, which allows you to write tests like this:\n\n```kotlin\nclass SomeTests : FlatSpec() {\n init {\n \"ListStack.pop\" should \"return the last element from stack” {\n // your test here\n }\n \"ListStack.pop\" should \"remove the element from the stack\" {\n // another test\n }\n }\n}\n```\n\nAs you can see, you start with some text, then the keyword should, then some more text, and finally the test as a block. This gives you a readable description of what your test is doing. The split of the test description into two parts means that the IDE / build tools can nest the test output into something like:\n\nListStack.pop should\n\n* return the last element from stack ok\n* remove the element from the stack ok\n\nAll tests need to be placed inside the init {} block. For those of you coming from a Scala background, this is because Kotlin doesn’t allow the body of the class to be treated as the constructor like you can in Scala.\n\nA quick example of another style is WordSpec, in which the tests are nested. So,\n\n\"ListStack.pop\" should {\n \"remove the last element from stack\" {\n // test 1\n }\n}\n\n\"ListStack.peek\" should {\n \"should leave the stack unmodified\" {\n // test 2\n }\n}\n\nI think this is fairly self explanatory. The rest of the testing styles are available on the KotlinTest homepage.\n\n### Matchers\n\nLet's move onto the matchers. When writing your tests in Java, it is common to use assertions like assertEquals(a, b). This is fine, but we can do something a bit more readable with KotlinTest. As a simple example, to assert two values are equal, we can say\n\n```kotlin\n\"a\" shouldBe \"a\" or \"a\" shouldEqual \"a\"\n```\n\nWe can do clever things with strings:\n\n```kotlin\nsomeStr should start with \"foo\"\nsomeStr should end with \"bar\"\nsomeStr should have substring \"xxx\"\n```\n\nOr with collections\n\n```kotlin\nmyList should have size 4\nmySet should contain element \"a\"\n```\n\nThere are many matchers available for collections, strings, longs, ints, etc.\n\nSometimes we need to assert that an exception is thrown under certain conditions. The typical way to do this in other test frameworks is to wrap the code in a try/catch and then assert false at the bottom of the try, eg\n\n```kotlin\ntry {\n // this code should throw an exception\n assert(false)\n} catch (Exception e) {\n // good\n}\n\n```\n\nWe can remove this boilerplate in KotlinTest using the `shouldThrow` function. Just wrap your code with this function, replacing T with the type (or supertype) of Exception you want to catch, eg\n\n```kotlin\nshouldThrow {\n // code that should throw an exception\n}\n```\n\nOne of the more tricky things in testing, is when you have code that completes non-deterministically. Perhaps you’re sending off an async call and need to wait until a reply comes back.\n\nThe naive way to do this is to sprinkle your test code with Thread.sleeps but how long to wait? You don’t want the time-out to expire prematurely. So if your call takes 2 seconds to complete, you set your sleep to 5 seconds. Until the time your build server is running slow, and 5 seconds wasn't enough, so you set it to 15 seconds. But now you wait 15 seconds every time regardless.\n\nAnother tool is to use countdown latches, and these are often my preferred choice. Have some code trigger the latch once it's completed (i.e. in a callback) and have the main test thread block on the latch.\n\nIf that doesn't work, KotlinTest introduces the eventually function. This allows you to repeatedly probe for a test condition and once it passes the function will return. This means you can wait up to a set time, but no more. It’s very easy to use, you just supply the max time you’re prepared to wait before considering it a failure. Extend the Eventually interface in your test class, e.g.:\n\n```kotlin\nClass MyTest : FlatSpec(), Eventually {\n Init {\n \"This test\" should \"finish quickly\" {\n eventually(5, TimeUnit.SECONDS) {\n // code here\n }\n }\n }\n}\n```\n\nNow if the assertions doesn't pass within 5 seconds, the test will fail. If the assertions pass quicker than 5 seconds, your test will return as soon as it can.\n\nKotlinTest borrows another feature from ScalaTest in the form of inspectors. Inspectors are helpers for assertions on elements of collections.\n\nLet's suppose you wanted to test that a collection of strings had one at most one string “root”, and the rest of the elements were not “root”, you could do this:\n\n```kotlin\nval count = strings.count { it == \"root\" }\n(count ==0 || count == 1) shouldBe true\n```\n\nWe can do this very easily using an inspector called forAtMostOne. This function will assert that there either zero or one elements pass the assertions, otherwise the test fails.\n\n```kotlin\nforAtMostOne(strings) { it == \"root\" }\n```\n\nThere are many inspectors: forAll, forNone, forSome, forExactly(k), forAtMostOne, forAtLeastOne. The full list can be found [here](https://github.com/kotlintest/kotlintest#inspectors)\n\nAnother quick example to assert that in a collection of people, some of them are called David some live in London, and some work for 51zero. (By some we mean at least 1, but not all).\n\n```kotlin\nforSome(people) { it .firstName() shouldBe \"David\" }\nforSome(people) { it .location() shouldBe \"London\" }\nforSome(people) { it .employer() shouldBe \"51zero\" }\n```\n\nWriting that without an inspector would be at least a few lines longer.\n\nThe final thing I want to mention is setting up and tearing down tests. We can do this before and after each test, or before and after each test suite (test suite is the class file). To do this we just override whichever methods we need, e.g.\n\n```kotlin\noverride fun beforeEach() {\n println(\"Test starting\")\n}\n\noverride fun afterEach() {\n println(\"Test completed\")\n}\n\noverride fun beforeAll() {\n println(\"Setting up my tests\")\n}\n\noverride fun afterAll() {\n println(\"Cleaning up after my tests\")\n}\n```\n\nThat’s all for now. This should help get you up and running and using Kotlin in your projects. In the next article, we’ll write about how you can create custom matchers to allow your own DSL syntax for complicated matchers.\n\nPlease let [us](http://www.51zero.com/about) know your experience of testing in Kotlin in the comments below.\n\n","author":"Stephen Samuel","date":"2016-05-10","type":"article","categories":["Kotlin","Testing"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin NetBeans plugin beta is out!","url":"https://blog.jetbrains.com/kotlin/2016/09/kotlin-netbeans-plugin-beta-is-out/","body":"\nToday we are happy to present the first BETA release of the Kotlin plugin for the NetBeans IDE.\n\nThe main features are:\n\n* Building and Running Your Code\n* Maven and Ant Support\n* Java Interoperability\n* Code Highlighting\n* Diagnostics\n* Code Completion\n* Navigation\n* Debugging\n* Unit Testing\n* Auto-Import\n* Mark Occurrences\n* Quick Search\n* Code Formatting\n\n## Installation\n\nTo give it a try you will need an installation of NetBeans 8.1. The beta version of Kotlin plugin is available from the [NetBeans Plugin Portal](http://plugins.netbeans.org/plugin/68590/kotlin).\n\nInstallation process:\n\n1. Download Kotlin plugin\n2. Launch NetBeans IDE\n3. Choose **Tools** and then **Plugins** from the main menu\n4. Switch to **Downloaded** tab\n5. On the **Downloaded** tab click **Add Plugins...** button\n6. In the file chooser, navigate to the folder with downloaded plugin. Select the NBM file and click OK. The plugin will show up in the list of plugins to be installed.\n7. Click **Install** button in the Plugins dialog\n8. Complete the installation wizard by clicking **Next**, agreeing to the license terms and clicking **Install** button.\n\n## Using Kotlin in NetBeans\n\nTo start using Kotlin in NetBeans you could create a new Java project (Maven- or Ant-based) or open an existing one. You can mix Java and Kotlin freely, Java classes are accessible from Kotlin and vice versa. At the moment plugin supports Kotlin 1.0.3.\n\nHere is a quick overview of the features.\n\n### Diagnostics\n\n[![diagnostics](https://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/09/diagnostics.png?zoom=1.5&resize=640%2C224&ssl=1)](https://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/09/diagnostics.png?ssl=1)\n\n### Code Completion\n\n[![completion](https://i1.wp.com/blog.jetbrains.com/kotlin/files/2016/09/completion.png?zoom=1.5&resize=640%2C297&ssl=1)](https://i1.wp.com/blog.jetbrains.com/kotlin/files/2016/09/completion.png?ssl=1)\n\n### Navigation\n\nFrom Kotlin to Kotlin:\n\n[![navigationk2k](https://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/09/navigationK2K.png?zoom=1.5&resize=640%2C160&ssl=1)](https://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/09/navigationK2K.png?ssl=1)\n\nFrom Kotlin to Java:\n\n[![navigationk2j](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/navigationK2J.png?zoom=1.5&resize=640%2C214&ssl=1)](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/navigationK2J.png?ssl=1)\n\nFrom Java to Kotlin:\n\n[![navigationj2k](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/navigationJ2K.png?zoom=1.5&resize=640%2C213&ssl=1)](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/navigationJ2K.png?ssl=1)\n\n### Debugging\n\nYou can\n\n* Set breakpoints\n* Use Step in/out/over\n* View local variables and contents of Kotlin objects\n\n[![debugging](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/debugging.png?zoom=1.5&resize=640%2C486&ssl=1)](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/debugging.png?ssl=1)\n\n### Unit Testing\n\nTo write tests in Kotlin you should have JUnit in the classpath of your project.\n\n[![junit](https://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/09/junit.png?zoom=1.5&resize=640%2C348&ssl=1)](https://i0.wp.com/blog.jetbrains.com/kotlin/files/2016/09/junit.png?ssl=1)\n\n### Auto-Import\n\n[![autoimport](https://i1.wp.com/blog.jetbrains.com/kotlin/files/2016/09/autoImport.png?zoom=1.5&resize=640%2C193&ssl=1)](https://i1.wp.com/blog.jetbrains.com/kotlin/files/2016/09/autoImport.png?ssl=1)\n\n### Mark Occurrences\n\n[![occurrences](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/occurrences.png?zoom=1.5&resize=325%2C115&ssl=1)](https://i2.wp.com/blog.jetbrains.com/kotlin/files/2016/09/occurrences.png?ssl=1)\n\n### Quick Search\n\n[![quicksearch](https://i1.wp.com/blog.jetbrains.com/kotlin/files/2016/09/quickSearch.png?zoom=1.5&resize=640%2C118&ssl=1)](https://i1.wp.com/blog.jetbrains.com/kotlin/files/2016/09/quickSearch.png?ssl=1)\n\n### Feedback Welcome\n\nYour feedback is very important. Feel free to add issues and feature requests in the [plugin issue tracker](https://github.com/Baratynskiy/kotlin-netbeans/issues).\n\nJust like Kotlin itself, the NetBeans plugin is an open-source project, so your contributions can help it evolve faster.\n\n","author":"Dmitry Jemerov","date":"2016-09-19","type":"article","categories":["Kotlin","Netbeans"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Type safe JavaFX CSS with TornadoFX","url":"https://www.youtube.com/watch?v=rjc8_HGHy3c","body":"\n\n\n\n","author":"Edvin Syse","date":"2016-04-24","type":"video","categories":["Kotlin","TornadoFx"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Creating a self-contained Kotlin program using Avian","url":"https://hackernoon.com/creating-a-self-contained-kotlin-app-using-avian-ca7f2987fdd5","body":"\n[Avian](https://readytalk.github.io/avian/) is a lightweight JVM that will allow you to create self-contained apps. That means that you can ship your app without forcing your users to install any JRE. In here, we will follow simple steps that are going to allow us to create a stand-alone hello-world app using Kotlin.\n\n## Why Kotlin?\n\nKotlin is a great language with a lot of potential. I am not going to go through all the advantages of it since a lot of people before me has done it already. So we will leave it at that, great language with a lot of potential. And if you want to read why, there’s plenty of info online.\n\n## Why Avian?\n\nOne of the biggest challenges that Java has is the fact that it requires a Java Runtime Environment. That means that if I write a Java program, every single one of my users will need to download, install, and maybe configure the JRE before they can even launch my program. And in some cases, people are going to prefer not to install certain software to avoid the hassle, if they don’t have a JRE already (or if they have a non compatible version of the JRE.)\n\n## The Result\n\nWhat we are going to finish with is a 1.9MB binary for macOS or 2.2MB for Linux (with some little changes it should work with the other supported platforms, see [here](https://github.com/ReadyTalk/avian/blob/master/README.md),) that once executed will greet the user and print all the arguments that it received. Like this:\n\n```\n$ ./hello Miguel Castiblanco\nHello from Kotlin and Avian\nargs:\n-Miguel\n-Castiblanco\n```\n\n## 1. Before we start\n\n * $JAVA\\_HOME must be pointing to the correct location\n * Kotlin must be installed, and kotlinc (Kotlin compiler) must be in $PATH\n * The commands below are written to work in macOS. Unless mentioned, the command should work in Linux by changing macosx to linux, and the architecture (if needed.) For example *macosx-x86\\_64* would become *linux-i386* or *linux-x86\\_64*\n * This tutorial is based on the [README](https://github.com/ReadyTalk/avian/blob/master/README.md) of Avian. Most of my work was to make it work with Kotlin instead of Java, and to put it in groups of instructions that makes sense for people new to Avian along with explanations of what we are doing.\n\n## 2. Getting and building Avian\n\nLet’s start by getting the latest version of Avian:\n\n```\n$ git clone https://github.com/ReadyTalk/avian.git\n```\n\nThen build it with the default configuration, and test that it’s working\n\n```\n$ cd avian\n$ make\n$ build/macosx-x86_64/avian -cp build/macosx-x86_64/test Hello\n```\n\nThe last command should print “hello, world!” if everything is correct.\n\n## 3. Writing our simple Kotlin program, and packing it\n\nLet’s create a folder, put our little Kotlin script there, and pack it into a jar.\n\n```\n$ cd ../\n$ mkdir helloKotlin && cd helloKotlin\n$ cat >Hello.kt <) {\n println(\"Hello from Kotlin and Avian\")\n println(\"args: \")\n args.forEach {\n println(\"-\\$it\")\n }\n}\nEOF\n$ kotlinc Hello.kt -include-runtime -d boot.jar\n```\n\n## 4. Preparing Avian’s runtime to be merged with Kotlin’s\n\nNotice that we are compiling including Kotlin’s runtime, that means that if you run un*zip -l boot.jar* you will see all Kotlin’s classes in there. This is important since we want a stand-alone application.\n\nWe are going to get Avian’s runtime and extract it, and also get the files needed to create a binary with Avian.\n\n```\n$ ar x ../avian/build/macosx-x86_64/libavian.a\n$ mkdir avian-cp\n$ cp ../avian/build/macosx-x86_64/classpath.jar avian-cp/avian-cp.jar\n$ cd avian-cp/\n$ unzip avian-cp.jar && rm -rf avian-cp.jar\n```\n\n## 5. Merging Avian, Kotlin, and our app in one jar\n\nHere we create one jar that has Avian’s runtime, Kotlin’s runtime, and our little application. We’ll just merge all the content that we extracted before from *avian-cp.jar* into *boot.jar* (which already has Kotlin and our code.)\n\n```\n$ mv ../boot.jar .\n$ zip -r boot.jar META-INF avian dalvik java libcore sun\n$ mv boot.jar ../ && cd ../\n```\n\nIf you run un*zip -l boot.jar* now, you will see that all the classes are now happy together.\n\n## 6. Creating a binary\n\nNow we have a self-contained jar. Left is only to use Avian to create a binary out of the jar. First we create an object from the jar.\n\n```\n$ ../avian/build/macosx-x86_64/binaryToObject/binaryToObject boot.jar \\boot-jar.o _binary_boot_jar_start _binary_boot_jar_end macosx x86_64\n```\n\nThe following command will create the c++ main class for our binary. Please notice that *FindClass* is looking for **HelloKt**, since the classes compiled with *kotlinc* wil have a *Kt* suffix (*javac* compiles *Hello.java* into *Hello.class*, whereas *kotlinc* compiles *Hello.kt* into *HelloKt.class.*)\n\n```\n$ cat >embedded-jar-main.cpp <(\"-Xbootclasspath:[bootJar]\");\n\nJavaVM* vm;\n void* env;\n JNI_CreateJavaVM(&vm, &env, &vmArgs);\n JNIEnv* e = static_cast(env);\n\njclass c = e->FindClass(\"HelloKt\");\n if (not e->ExceptionCheck()) {\n jmethodID m = e->GetStaticMethodID(c, \"main\", \"([Ljava/lang/String;)V\");\n if (not e->ExceptionCheck()) {\n jclass stringClass = e->FindClass(\"java/lang/String\");\n if (not e->ExceptionCheck()) {\n jobjectArray a = e->NewObjectArray(ac-1, stringClass, 0);\n if (not e->ExceptionCheck()) {\n for (int i = 1; i < ac; ++i) {\n e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i]));\n }\n\ne->CallStaticVoidMethod(c, m, a);\n }\n }\n }\n }\n\nint exitCode = 0;\n if (e->ExceptionCheck()) {\n exitCode = -1;\n e->ExceptionDescribe();\n }\n\nvm->DestroyJavaVM();\n\nreturn exitCode;\n}\nEOF\n```\n\nNow we will compile the C++ class into an object, and link all the objects (notice that in step 4 we copied a bunch of Avian’s objects into the current folder) to finally create our binary, that will be called *hello*.\n\n**For macOS:**\n\n```\n$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin \\\n -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o\n$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello -framework CoreFoundation\n$ strip -S -x hello\n```\n\n**For Linux:**\n\n```\n$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \\\n -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o\n$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello\n$ strip --strip-all hello\n```\n\n## 7. Run it\n\nNow we can finally run it and see how it works\n\n```\n$ ./hello Kotlin Avian\nHello from Kotlin and Avian\nargs:\n-Kotlin\n-Avian\n$ ls -lha hello\n-rwxr-xr-x 1 starcarr starcarr 2.0M Feb 8 17:03 hello\n```\n\n## Conclusions\n\n * This process is long and of course it can potentially be transformed into a script that does all the work for us. That being said, it’s important to take the time to do it this way at least once in order to understand how Avian works so that we can troubleshoot when things go south\n * Avian is opening the door to stand-alone Kotlin and Java apps, which will allow us to create script or utility applications that can be distributed easily for JRE-less machines\n * The total size of the application was 1.9MB (2.2MB in Linux), which goes to show that Avian is effectively lightweight\n","author":"Miguel Castiblanco","date":"2017-02-09","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin Post-1.0 Roadmap","url":"http://blog.jetbrains.com/kotlin/2016/04/kotlin-post-1-0-roadmap/","body":"\nIt’s been almost two months since Kotlin 1.0 was released, and the team is now switching from stabilisation and bug fixes to new feature work, so it’s a great time to talk about our plans for the future.\n\nWe’ve already published our [Android roadmap](http://blog.jetbrains.com/kotlin/2016/03/kotlins-android-roadmap/), but there are many other areas where we’re applying our efforts. Our current development is organised in two main branches:\n\n* **Kotlin 1.0.x** which will be a series of releases containing bug fixes, updates to tooling, IDE support and other areas which do not affect the core language. 1.0.x releases will be published on a regular basis once every several weeks.\n* **Kotlin 1.1** which will contain major new language features, along with all the improvements from the 1.0.x branch. This will be a feature-driven release, and we aren’t announcing any specific time frame for it.\n\nLet’s look at the plans for each area in more detail, starting with the big ones.\n\n## New Language Features\n\nBefore we can start talking about specific features, the **big disclaimer**: everything we’re talking about here is still in the design phase, and features may end up being changed dramatically or dropped entirely as we move forward with the design, implementation and feedback gathering process. So, no guarantees.\n\n### async/await/yield\n\nThe most important feature that we’re designing right now is support for **coroutines** (async/await/yield). By now, the async/await pattern has found its way into many different languages, including C#, Python and Dart, and we want to support this in Kotlin as well. However, that’s not the end of the story: we want to put the specific code execution semantics into the library, rather than the compiler.\n\nThe compiler will take care of transforming the function used as a coroutine into a form allowing to suspend and resume its execution. The actual execution of a coroutine (the initial invocation, as well as resuming the execution after a suspension point) will be the responsibility of the support library. Therefore, the same mechanism will allow us to support many different patterns: generators (`yield`), asynchronously executed functions (`async`/`await`), Go-like channels and goroutines, as well as potentially others which haven’t even been invented yet.\n\nNote that we’re still in the process of estimating the effort needed to implement this feature, and we don’t know whether it would be reasonable to support it in the 1.1 timeframe or it would be postponed to a later release.\n\n### Other Language Features\n\nWe’ve received quite a lot of feedback from Kotlin 1.0, and we were quite happy to see that a lot of the requests were asking for the same features. We’ve chosen the ones that come up the most often, and have prioritised them for Kotlin 1.1. Those we’re reasonably sure about are:\n\n* **Data class hierarchy support** will remove many of the current restrictions on data class inheritance, for example, allowing you to represent an algebraic data type as a series of data classes nested in a sealed class:\n ```kotlin\n sealed class C {\n data class A(val x: X, val y: Y) : C() { ... }\n }\n ```\n* **Type aliases** will allow to assign a short name to a type (for example, a function type, or a generic type with a long signature):\n `typealias MouseEventHandler = (MouseEvent) -> Unit`\n* **Destructuring in lambdas** will allow you to easily unpack a data class instance or another object supporting the destructuring protocol when it’s passed as a parameter to a lambda:\n `myMap.forEach { (key, value) -> println(key+value) }`\n* **Bound method references** will allow to create a method reference that invokes a method on a specific object instance, and doesn’t require passing it as a parameter:\n `letters.filter(\"abc\"::contains)`\n* **Local delegated properties** will allow you to define a local variable as a delegated property:\n `fun foo() { val x by lazy { ... } }`\n\n## Java 8/9 Support\n\nAs of version 1.0, Kotlin targets Java 6 only. This means that the generated bytecode does not make use of any features added in Java 7 or 8, and the standard library only exposes the APIs that existed in Java 6.\n\nOver the course of 1.0.x and 1.1 releases and beyond, we plan to remove these restrictions, and to give you the choice of the JVM version that you’re targeting. Java 6 is still going to be supported, but if you choose to target Java 8, we’ll make use of that. The standard library will let you use the new Java 8 APIs, such as the stream API, and the compiler will use the newer bytecode features, such as the support for default methods in interfaces. We also plan to support Project Jigsaw (the JDK 9 module system) by the time JDK 9 is released.\n\n## JavaScript Support\n\nWhen we started finalizing the 1.0 release, we decided to suspend work on JavaScript support and to focus on the JVM as the main supported platform for the release. Now that 1.0 is out, we’ve resumed work on JS, and we’re moving towards our goal of letting you write the business logic of your application only once and to run it both on the backend and in the user’s browser.\n\nOur main priorities for the short term are filling in the missing language features and better integration with the overall JavaScript infrastructure (starting with support for JS module systems). We also plan to leverage the huge set of strongly-typed API definitions for most major JS libraries, which has been accumulated by the TypeScript community. We’ll provide a tool to convert those definitions into Kotlin code, letting you use the libraries from Kotlin with a fully typed API and very little effort spent on integration.\n\n## IDE Features\n\nIn the IDE space, our current priorities are as follows:\n\n* **Framework support**: We plan to extend the unparalleled level of Java enterprise framework support offered by IntelliJ IDEA Ultimate so that it works equally well for Kotlin. This will be a gradual process happening in parallel inside IntelliJ IDEA and inside the Kotlin plugin; the first batch of Spring support features is already available in Kotlin 1.0.2 EAP.\n* **Intentions and Quickfixes:** In our view, one of the main roles of an IDE is teaching you how to use the language well and helping you get back to speed if you make a mistake, by providing code improvement suggestions and automatic quickfixes. Kotlin 1.0 already contains a nice set of tools in this area, and we’re going to expand on it in the 1.0.x and 1.1 updates. As one example, we’re building tools that can convert imperative-style loops into code written in the functional style, using functions such as map and filter.\n* **Other Improvements:** Other things on our roadmap include new refactorings such as Inline Method, a more robust and flexible formatter, support for diagrams for Kotlin code, and more.\n\n## Other Tooling Improvements\n\nThe Android roadmap post already mentioned some of the improvements that we plan to make in our tools, such as support for incremental compilation with Gradle and support for Android Lint checks. Both of these features are already available in Kotlin 1.0.2 EAP, and will receive further improvements later on.\n\n## Summary\n\nAs you can see, there are quite a lot of exciting things coming, and there’s plenty of opportunity for you to get involved. Stop by our [Slack chat](http://kotlinslackin.herokuapp.com/), try out the [EAP builds](https://discuss.kotlinlang.org/c/eap), file [issues](http://youtrack.jetbrains.com/issues/KT) – the future of Kotlin depends on you, our users, and we’re always happy to hear anything that you have to say.\n\n","author":"Dmitry Jemerov","date":"2016-04-14","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1.1 is out","url":"https://blog.jetbrains.com/kotlin/2017/03/kotlin-1-1-1-is-out/","body":"\nToday we’re releasing the first bugfix update for **Kotlin 1.1**. The primary focus of this update is to address regressions causing incorrect code generation; we wanted to get those fixes out as quickly as possible. The details are available in the [changelog][].\n\nThe specific changes worth highlighting are:\n\n * **Gradle incremental compilation** is now enabled by default. You can still turn it off as described in the [documentation][] if you need to.\n * Kotlin plugins are now available in the **[Gradle plugin portal][]**. See the [documentation][documentation 1] for usage instructions.\n * Using function types with receivers as parameter types of **JavaScript external declarations** is no longer allowed. Previously, lambdas passed to such parameters weren’t invoked with correct arguments, and there’s no easy workaround for this issue, so for now we’ve decided to disable the functionality.\n\nWe’ve also updated the Kotlin [Eclipse][] and [NetBeans][] plugins to include Kotlin 1.1.1, so you can enjoy the benefits of the new Kotlin version regardless of your IDE choice.\n\n## How to update ##\n\nTo update the IDEA plugin, use Tools | Kotlin | Configure Kotlin Plugin Updates and press the “Check for updates now” button. Also, don’t forget to update the compiler and standard library version in your Maven and Gradle build scripts.\nThe command-line compiler can be downloaded from the [Github release page][].\n\nAs usual, if you run into any problems with the new release, you’re welcome to ask for help on the [forums][], on Slack (get an invite [here][]), or to report issues in the [issue tracker][].\n\nLet’s Kotlin!\n\n[changelog]: https://github.com/JetBrains/kotlin/blob/1.1.1/ChangeLog.md\n[documentation]: http://kotlinlang.org/docs/reference/using-gradle.html#incremental-compilation\n[Gradle plugin portal]: https://plugins.gradle.org/\n[documentation 1]: http://kotlinlang.org/docs/reference/using-gradle.html\n[Eclipse]: https://marketplace.eclipse.org/content/kotlin-plugin-eclipse\n[NetBeans]: http://plugins.netbeans.org/plugin/68590/kotlin\n[Github release page]: https://github.com/JetBrains/kotlin/releases/tag/v1.1.1\n[forums]: https://discuss.kotlinlang.org/\n[here]: http://kotlinslackin.herokuapp.com/\n[issue tracker]: https://youtrack.jetbrains.com/issues/KT\n","author":"Dmitry Jemerov","date":"2017-03-14","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Bytecode behind coroutines in Kotlin","url":"http://jonnyzzz.com/blog/2017/04/26/corotines-or-state-machine/","body":"\nA simple suspend function, and it’s bytecode.\n\nThe new thing in Kotlin 1.1 is [coroutines](http://kotlinlang.org/docs/reference/coroutines.html). As we know from the documentation, it is the `suspend` keyword that was added to the language. The rest is implemented as libraries.\n\nLet’s take a look at the bytecode side of this feature.\n\n# An Empty Suspend function\n\nI have the following code snippet:\n\n```kotlin\nsuspend fun b() {}\n```\n\nLet’s take a look to the bytecode from this method. For the experiment, I use Kotlin 1.1.1 with IntelliJ IDEA 2017.1. Results may depend on version. I use `javap -c` to generate those dumps\n\n```\npublic static final java.lang.Object b(kotlin.coroutines.experimental.Continuation);\n Code:\n 0: aload_0\n 1: ldc #13 // String $continuation\n 3: invokestatic #19 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V\n 6: getstatic #25 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;\n 9: areturn\n```\n\nThe interface `Continuation` is declared in the Kotlin standard library, see [documentation](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/). It contains `context` and methods to complete continuation: `resume` and `resumeWithException`.\n\n# A Trivial Suspend function\n\n```kotlin\nsuspend fun b2() {\n a()\n c()\n}\n```\n\nHere `a()` and `c()` are calls to ordinary Java methods, which were declared in Kotlin without the `suspend` keyword.\n\n```\npublic static final java.lang.Object b2(kotlin.coroutines.experimental.Continuation);\n Code:\n 0: aload_0\n 1: ldc #13 // String $continuation\n 3: invokestatic #19 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V\n 6: invokestatic #29 // Method a:()V\n 9: invokestatic #31 // Method c:()V\n 12: getstatic #25 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;\n 15: areturn\n```\n\nAs we see from this code, there is nothing special done to the method. The only return value and additional parameter were added.\n\n# A suspend function with a suspend call\n\n```kotlin\nsuspend fun b3() {\n a()\n b3()\n c()\n}\n```\n\nIn this example, we call `b3()` suspend function from itself. Here `a()` and `c()` are calls to ordinary Java methods, which were declared in Kotlin without `suspend` keyword. The generated code now looks way different.\n\n```\npublic static final java.lang.Object b3(kotlin.coroutines.experimental.Continuation);\n descriptor: (Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;\n Code:\n 0: aload_0\n 1: ldc #13 // String $continuation\n 3: invokestatic #19 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V\n 6: new #34 // class streams4/ZKt$b3$1\n 9: dup\n 10: aload_0\n 11: invokespecial #38 // Method streams4/ZKt$b3$1.\"\":(Lkotlin/coroutines/experimental/Continuation;)V\n 14: getstatic #25 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;\n 17: aconst_null\n 18: invokevirtual #42 // Method streams4/ZKt$b3$1.doResume:(Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;\n 21: areturn\n```\n\nInstead of having the method in-place, it now generates an inner class for the state-machine to implement the `suspend`.\n\nThe class `streams4/ZKt$b3$1` is generated as follows\n\n```\nfinal class streams4.ZKt$b3$1 extends kotlin.coroutines.experimental.jvm.internal.CoroutineImpl {\n public final java.lang.Object doResume(java.lang.Object, java.lang.Throwable);\n descriptor: (Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;\n Code:\n 0: invokestatic #13 // Method kotlin/coroutines/experimental/intrinsics/IntrinsicsKt.getCOROUTINE_SUSPENDED:()Ljava/lang/Object;\n 3: astore_3\n 4: aload_0\n 5: getfield #17 // Field kotlin/coroutines/experimental/jvm/internal/CoroutineImpl.label:I\n 8: tableswitch { // 0 to 1\n 0: 32\n 1: 58\n default: 74\n }\n 32: aload_2\n 33: dup\n 34: ifnull 38\n 37: athrow\n 38: pop\n 39: invokestatic #23 // Method streams4/ZKt.a:()V\n 42: aload_0\n 43: aload_0\n 44: iconst_1\n 45: putfield #17 // Field kotlin/coroutines/experimental/jvm/internal/CoroutineImpl.label:I\n 48: invokestatic #27 // Method streams4/ZKt.b3:(Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;\n 51: dup\n 52: aload_3\n 53: if_acmpne 66\n 56: aload_3\n 57: areturn\n 58: aload_2\n 59: dup\n 60: ifnull 64\n 63: athrow\n 64: pop\n 65: aload_1\n 66: pop\n 67: invokestatic #30 // Method streams4/ZKt.c:()V\n 70: getstatic #36 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;\n 73: areturn\n 74: new #38 // class java/lang/IllegalStateException\n 77: dup\n 78: ldc #40 // String call to 'resume' before 'invoke' with coroutine\n 80: invokespecial #44 // Method java/lang/IllegalStateException.\"\":(Ljava/lang/String;)V\n 83: athrow\n\n streams4.ZKt$b3$1(kotlin.coroutines.experimental.Continuation);\n descriptor: (Lkotlin/coroutines/experimental/Continuation;)V\n Code:\n 0: aload_0\n 1: iconst_0\n 2: aload_1\n 3: invokespecial #58 // Method kotlin/coroutines/experimental/jvm/internal/CoroutineImpl.\"\":(ILkotlin/coroutines/experimental/Continuation;)V\n 6: return\n}\n```\n\nThe implementation of `b3()` function is moved to a state machine anonymous object. The main method of the inner object does a switch over states of the state machine. The `b3()` function is split by every `suspend` function call. On the example below, we have only 2 states. This is up to helper functions to assert the machine is always in a correct state.\n\nOn every `suspend` function call, Kotlin creates an object to encapsulate the state of the state machine, that is created to implement the continuations on top of JVM.\n\n# Conclusion\n\nCoroutines in Kotlin are awesome, easy and powerful constructs that give us the power to fight the complexity (by the cost of an extra abstraction level). I’m looking forward to using coroutines to simplify asynchronous code in my apps.\n\nFor more information and details see [Kotlin coroutines](http://kotlinlang.org/docs/reference/coroutines.html) documentation.\n","author":"Eugene Petrenko","date":"2017-04-26","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Upgrade your workflow with 0-installation kotlin scriptlets","url":"http://holgerbrandl.github.io/kotlin/2016/12/02/mini_programs_with_kotlin.html","body":"\nIn common bioinformatics/scientific workflows black magic bash hacking skills are often required and used to process data. This is because these workflows tend to live in the bash-shell, and for many data processing tasks there is no actual direct tool. To make data flow nevertheless _solution repositories_ like [biostar](https://www.biostars.org/) or [stackoverflow](http://stackoverflow.com/) tend to suggest crazy combinations of `perl`, `grep`, `awk` or `sed` mixed with various amounts of `bash`. Such solutions often lack engineering quality, depend on specific platforms and versions, and tend to very cryptic even for well-trained data monkeys. More high-level solution in _python_ or _R_ could be used as well, but hardly ever run without additional setup efforts.\n\nTo overcome this problem, I’ve evolved a small extension tool to named [`kscript`](https://github.com/holgerbrandl/kscript) over the last months. It allows to easily embed [Kotlin](https://kotlinlang.org/) scriptlets into the shell, and ships with features like compile-jar-caching and automatic dependency resolution. Just see its [github page](https://github.com/holgerbrandl/kscript) for details and examples.\n\nAlthough `kscript` has helped to create readable kotlin solutions for a range of data flow problems, it was still a bit tedious to ship around developed solutions in a concise and user-friendly manner. To overcome this problem, I’ve recently enhanced `kscript` to also allow for URLs as scriptlet sources.\n\nLet’s do an example. Imagine you’d need to filter a list of genomic sequences saved in a [fasta-formatted](https://en.wikipedia.org/wiki/FASTA_format) file by length. This is how the data may look like:\n\n```\n>HSBGPG Human gene for bone gla protein (BGP)\nGGCAGATTCCCCCTAGACCCGCCCGCACCATGGTCAGGCATGCCCCTCCTCATCGCTGGGCACAGCCCAGAGGGT\nATAAACAGTGCTGGAGGCTGGCGGGGCAGGCCAGCTGAGTCCTGAGCAGCAGCCCAGCGCAGCCACCGAGACACC\nCTCCAGGCACCCTTCTTTCCTCTTCCCCTTGCCCTTGCCCTGACCTCCCAGCCCTATGGATGTGGGGTCCCCATC\nATCCCAGCTGCTCCCAAATAAACTCCAGAAG\n>HSGLTH1 Human theta 1-globin gene\nCCACTGCACTCACCGCACCCGGCCAATTTTTGTGTTTTTAGTAGAGACTAAATACCATATAGTGAACACCTAAGA\nCGGGGGGCCTTGGATCCAGGGCGATTCAGAGGGCCCCGGTCGGAGCTGTCGGAGATTGAGCGCGCGCGGTCCCGG\nGATCTCCGACGAGGCCCTGGACCCCCGGGCGGCGAAGCTGCGGCGCGGCGCCCCCTGGAGGCCGCGGGACCCCTG\nTCAGCCCCGCGCTGCAGGCGTCGCTGGACAAGTTCCTGAGCCACGTTATCTCGGCGCTGGTTTCCGAGTACCGCT\nGAACTGTGGGTGGGTGGCCGCGGGATCCCCAGGCGACCTTCCCCGTGTTTGAGTAAAGCCTCTCCCAGGAGCAGC\nCTTCTTGCCGTGCTCTCTCGAGGTCAGGACGCGAGAGGAAGGCGC\n>ARGH1 Transcriptional regulartor\nATCCAGGGCGATTCAGAGGGCCCCGGGCCACGTTATCTCGGCGCTGGTTTCGCGCTGGTTTCGCGCTGGTTTCGC\nCTGGTTTCC\n```\n\nFor sure, there are many different [ways to solve](https://www.biostars.org/p/79202/) this problem. E.g. using a tool called `samtools faidx` with downstream filtering of its output using `awk`. Or by reformating the multi-line fasta into single-line via `perl` plus some `awk` and so on. [BioPyton](https://github.com/biopython/biopython.github.io/) or [BioPerl](http://bioperl.org/) also do the trick, are very readable, but require installation and additional setup efforts.\n\nTo allow for **0-installation scriptlets** that do their own automatic dependency resolution, `kscript` comes to rescue. Here’s a Kotlin solution for the filter problem from above, which we’ll work through step by step:\n\n```kotlin\n//DEPS de.mpicbg.scicomp:kutils:0.4\n//KOTLIN_OPTS -J-Xmx2g\n\nimport de.mpicbg.scicomp.bioinfo.openFasta\nimport java.io.File\nimport kotlin.system.exitProcess\n\nif (args.size != 2) {\n System.err.println(\"Usage: fasta_filter \")\n exitProcess(-1)\n}\n\nval fastaFile = File(args[0])\nval lengthCutoff = args[1].toInt()\n\nopenFasta(fastaFile).\n filter { it.sequence.length >= lengthCutoff }.\n forEach { print(it.toEntryString()) }\n```\n\n* First a single dependency is added that provides a Kotlin API to parse fasta-formatted data.\n* Because some of the sequences might be large we want to run with 2gb of memory.\n* Since it is supposed to be a self-contained mini-program it ships a simplistic CLI involving just an input file and the length-cutoff.\n* The implementation is straightforward: We create an iterator over the entries in the fasta-file, which is filtered by length, and the remaining entries are printed to stdout.\n\nBecause of Kotlin’s nice and concise collections API and syntax, the solution should be readable almost even to non-developers. ;-)\n\nPreviously `kscript` allowed to run such scriptlets either from a file or inlined (See its [docs]((https://github.com/holgerbrandl/kscript)) for more examples):\n\n```kotlin\n## simply read the script from stdin\necho 'println(\"hello world\")' | kscript -\n\n## or read it from a file\necho 'println(\"hello world\")' > test.kts\nkscript test.kts\n```\n\nHowever, since recently `kscript` also can **now also read URLs** which elevates its usage to a new level: The fasta length filter scriplet from above was deposited as a [gist](https://gist.github.com/holgerbrandl/521a5e9b1eb0d5b443b82cf13f66074f) on github, and we can now simply write\n\n```bash\nkscript https://git.io/v1ZUY test.fasta 20 > filtered.fasta\n```\n\nTo further increase readability and convenience, we can `alias` the first part\n\n```bash\nalias fasta_length_filter=\"kscript https://git.io/v1ZUY\"\n\nfasta_length_filter ~/test.fasta 20 > filtered.fasta\n```\n\nWhen being invoked without arguments `fasta_length_filter` will provide just the usage info.\n\nDepending on the users’ preference the URL could point either to the master revision of the gist or to a particular revision for better reproducibility. Since the scriplet is versioned along with its dependencies (which ware fetched via `maven`), this approach does not depend on API stability for the external libraries being used – a common problem which is tedious to overcome when working with python, R or perl! In contrast `kscript` solutions provide absolute **long-term stability** (within the limits of a hardly ever changing JVM and the kotlin compiler).\n\nIn this post I’ve discussed how to write versioned, bootstrapping mini-programs using `kscript` and `Kotlin`. In my next posting I’ll talk about the support APi for `kscript` to allow for `awk`-like one-liners written in Kotlin to please they eye instead of being confusing and `aw(k)`ful.\n\n","author":"Holger Brandl","date":"2016-12-02","type":"article","categories":["Kotlin","Scripts"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Custom Views in Android with Kotlin","url":"https://antonioleiva.com/custom-views-android-kotlin/","body":"","author":"Antonio Leiva","date":"2016-12-27","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Android + Kotlin = <3","url":"http://blog.zuehlke.com/en/android-kotlin/","body":"\nThe Android SDK has come a long way since its early days to make developing for Android as comfortable and efficient as possible. Yet there’s one thing that still gets in our way: The Java language. While more modern languages like C# or Swift make it possible to write code that is elegant and at the same time easy to read and understand, we’re still stuck with Java 7 for Android Development. Its cumbersome syntax for executing code on a different thread asynchronously, for example, or the fact that you require separate libs for even the most basic tasks like null-safe string comparison really make it a pain for development.\n\n## A New Hope\n\nAt this year’s Berlin DroidCon, I found one session in the conference schedule very intriguing: [A talk by Svetlana Isakova from JetBrains](http://www.droidcon.de/session/kotlin-swift-android) on [the Kotlin language](http://kotlinlang.org/) – “The Swift of Android”, according to the session title. Of course I attended, and during the talk I couldn’t help but start to smile, and that smile grew bigger and bigger: Kotlin and its accompanying extensions and plugins for Android addressed so many annoying issues of Java development for Android! No more enviously looking over to Apple’s Swift for iOS development! Also I found the syntax to be very intuitive. I simply had to try it out ASAP – and what better opportunity to do so than Zühlke’s educational Camp?\n\n## An Easy Language To Get Into\n\nFor the 2015 Camp, there were already plans for exploring the development for Android Wear by writing an app that connected to a sensor via Bluetooth Low Energy. The app should get historic data from the sensor and forward it to a connected Android Wear device, including notifications for certain events.\n\nThe colleague who was going to develop the Android app together with me wasn’t aware of my decision to use Kotlin for the project until right before we started coding. But nevertheless, we both were able to pick up the new language and start writing our app very quickly. This is due to several things.\n\nFirst of all, the [reference documentation](http://kotlinlang.org/docs/reference/) is very well written and easy to get into. JetBrains also provides a plugin for IntelliJ, Android Studio and Eclipse that greatly helps development in Kotlin. The Android Studio plugin we used not only provides proper debugging, auto-completion, code navigation and full refactoring support, but it also lets developers convert existing Java code files to Kotlin with just one click.\n\nAnother thing that makes it easy to use Kotlin in your Android project is the fact that, much like Scala, it’s **100% interoperable with Java code**! Kotlin compiles to regular Java Byte Code, and you can use existing Java classes in your project from Kotlin and vice versa. If you are familiar to Android development and want to write a new Activity you can do it like this:\n\n```kotlin\nclass MyActivity : Activity() {\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n ...\n }\n}\n```\n\nSimply inherit from `Activity` as before! The language is different, but you can use the framework and your own existing code, or for that matter, any existing Java library. Therefore you can gradually migrate to Kotlin if you don’t want to convert all your Java code to Kotlin right away.\n\nThe most important thing though is the incredible **ease of use** of the language. Being under development since 2010 and having gone open source in 2012, Kotlin has become very mature by now. It has adapted the great features of so many other languages. Here are some examples.\n\n## Some Nifty Kotlin Features\n\nWhen adding a property to your class, you don’t write the backing field and getters and setters separately. Instead, you do:\n\n```kotlin\npublic var context: Context? = null\n get\n set (value) {\n $context = value\n if (context != null) {\n setupBluetooth()\n }\n }\n```\n\nLooks familiar? Yup, that’s **C#-style properties** right there, which are accessed without calling the getter/setter explicitly. Also **classes and their member functions are final by default** and need to be declared `open` or `abstract` in order to be overridden.\n\nLike Scala, Kotlin does away with static methods and fields, which are so easily misused in Java. Instead of using those, Kotlin facilitates the declaration of **singleton objects**. Instead of declaring a class with some “instance” method, you simply declare an object right away, which can be used directly:\n\n```kotlin\nobject MySingleton {\n fun myFunction() { [...] }\n}\nMySingleton.myFunction()\n```\n\n**Null-safety** is also an important aspect of Kotlin. Every type is non-nullable by default, and you get a compile error when trying to assign or pass `null` to it. A type is made nullable by putting a question mark behind it. When accessing a nullable variable, Kotlin enforces a null check:\n\n```kotlin\nvar foo: String? = \"bar\" // foo is nullable now\nvar length = foo.length() // Compile error\nvar character = foo?.charAt(0) // OK; result is null if foo == null\nvar length2: Int = if (foo != null) foo.length() else 0 // Inlined null check\nvar nonNullFoo: String = foo ?: \"baz\" // Elvis operator; result is \"baz\" if foo = null\nvar letter = foo?.subSequence(0, 1) ?: return\nif (foo != null) { // Null check in the surrounding code\n character = foo.last() // -> Smart-cast to non-null\n}\nvar bang = foo!!.capitalize() // Forced to non-null. CAUTION: If it is null, you get an NPE!\n```\n\nThe concept is similar to Swift’s Optionals or Nullable Types in C#, though the syntax is a little different here. But it’s extremely comfy to use, and it prevents the dreaded `NullPointerException`s effectively.\n\nIf you’re missing a useful method on a foreign class, simply write an **extension function**:\n\n```kotlin\nfun String?.append(other: String): String {\n if (this == null) {\n return other\n }\n return this + other\n}\nvar hi: String? = \"Hello \"\nvar all = hi.append(\"World\")\n```\n\nNotice how the method extends the _nullable_ String? This way you can gracefully handle `null` objects without using null checks as shown above.\n\n## At last – Lambdas!\n\nAnd last but not least there’s Kotlin’s **Lambda** support. Especially in the context of any asynchronous communication, this is a godsend. For example, lambdas provide an elegant way of handling the many asynchronous callbacks that are used by Android’s Bluetooth Low Energy API. The syntax for declaring and using lambdas looks like this:\n\n```kotlin\nvar filtered = intArray.filter { it > 0 }\nintArray.forEachIndexed { index, element ->\n println(index + “:” + element)\n}\n```\n\nAnd here’s a function declaration that takes a lambda argument:\n\n```kotlin\nfun myFunction(param1: String, callback: (result: Int?, error: String?) -> Unit) {\n [...]\n}\n```\n\nWhen passing Lambdas to functions, they are usually in-lined in the function call, but you can also assign them to variables as **first-class objects** and pass them around later. Here’s how that looks like:\n\n```kotlin\nprivate var myCallback: Function1 = { param1: String ->\n println(\"Hi $param1\")\n}\n```\n\nAnd it doesn’t stop there; these features of Kotlin and many more make it possible to write code that’s elegant and easily understandable. But let’s get into some Android stuff.\n\n## Android Development With Pleasure\n\nIn addition to Kotlin’s own features, the [Anko library](https://github.com/JetBrains/anko) provides Extensions that eliminate a lot of the boilerplate code typically found in Android projects. One example is the **simplified “toast” statement**. Instead of the usual “Toast-makeText-context-content-length-show” sermon, you just do:\n\n```kotlin\ntoast(\"A toast to Android!\")\n```\n\nThe **findViewById** procedure has also been simplified:\n\n```kotlin\nval myText: TextView = find(R.id.myTextView)\n```\n\n**View hierarchies** can be quickly defined in Kotlin in the Activity code, including layout and listeners:\n\n```kotlin\nlinearLayout {\n button(\"Login\") {\n textSize = 26f\n onClick {\n doSomeStuff()\n }\n }.layoutParams(width = wrapContent) {\n horizontalMargin = dip(5)\n topMargin = dip(10)\n }\n}\n```\n\nAnother extremely helpful feature is the simplified use of Android’s ugly and unwieldy `AsyncTask`. With Anko, **executing asynchronous code** on a worker thread and processing results on the UI thread is as simple as:\n\n```kotlin\nasync {\n doSomeWork() // Long background task\n uiThread {\n result.text = \"Done\"\n }\n}\n```\n\nTired of **SQLite handling**, with all its `Cursor` handling and countless `try...catch` blocks? Just extend Anko’s `ManagedSQLiteOpenHelper`! It contains lots of little utilities that greatly simplify your database access code. Here’s an `INSERT` using your `ManagedSQLiteOpenHelper`:\n\n```kotlin\nuse { // Now \"this\" is the SQLiteDatabase, opened for read/write\n try {\n insert(\"ShoppingList\", // Table name\n \"id\" to item.id,\n \"title\" to item.title,\n \"checked\" to item.checked)\n } catch (exception: SQLiteException) { // SQL exceptions can still occur, of course\n error(\"INSERT threw exception: $exception\")\n }\n} // At the end of the block the DB is automatically closed\n```\n\nLooks neat? Wait till you see some `SELECT` code:\n\n```kotlin\nvar result: List = ArrayList()\nuse {\n try {\n result = select(\"ShoppingList\", \"id\", \"title\", \"checked\")\n .where(\"checked = {checkedArg}\", \"checkedArg\" to 1)\n .orderBy(\"id\", SqlOrderDirection.ASC)\n .exec {\n parseList(classParser())\n }\n } catch (exception: SQLiteException) {\n error(\"SELECT threw exception: $exception\")\n }\n}\n// Now process the result list\n```\n\nHow’s that for brevity? Just assemble your `SELECT` statement using fluent-style syntax, then automatically transform the returned `Cursor` into a `List` of your data items. The Parser is automatically generated from your data class, provided it has a constructor that matches the selected columns.\n\nAnd this is just the tip of the iceberg! Anko also provides simplified mechanisms for Intent dispatching, Service retrieval, Logging and a lot more.\n\n## Conclusion\n\nHaving tried out Kotlin in the context of Android development now, I can definitely see it becoming my new language of choice for Android development. It’s well made, mature and makes coding an absolute joy. The official Android documentation may be written for Java, but it’s easy to “translate” it to Kotlin, so any Android developer should definitely give Kotlin & Anko a try. Here’s hoping that Google will provide an Android API reference & guide in Kotlin in the near future, and that it will eventually become the de-facto standard for Android!\n\n","author":"Michael Sattler","date":"2015-07-20","type":"article","categories":["Kotlin","Android"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Kotlin 1.1-M03 is here!","url":"https://blog.jetbrains.com/kotlin/2016/11/kotlin-1-1-m03-is-here/","body":"\nWe are pleased to announce the third milestone of the upcoming Kotlin 1.1. This release brings new language features as well as improvements and fixes in the JavaScript backend, compiler and IDEA plugin. The new release also includes all tooling features introduced in Kotlin 1.0.5, and is compatible with IntelliJ IDEA 2016.3 EAP and Android Studio 2.2 and 2.3.\n\nAs with other milestone releases, we give **no backwards compatibility guarantees** for new language and library features. Anything introduced in milestone releases of 1.1 is **subject to change** before the final 1.1 release.\n\nPlease do share your feedback regarding the new features or any problems that you may run into with this release, via [YouTrack](https://youtrack.jetbrains.com/issues/KT), [forums](https://discuss.kotlinlang.org) and [Slack](http://kotlinlang.slack.com/).\n\nThe full changelog for 1.1-M03 is available [here](https://github.com/JetBrains/kotlin/blob/1.1-M03/ChangeLog.md).\n\n## Underscore for unused symbols\n\nYou can now use an underscore instead of the name of an unused parameter of a lambda:\n\n```kotlin\nfoo { _, x -> ... }\n```\n\nAnd an unused variable name in destructuring declarations can now be replaced with an underscore as well.\n\n```kotlin\nval (x, _, z) = expr\n```\n\nBoth cases are described in detail in the appropriate [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/underscore-for-unused-parameters.md).\n\n## Underscore in numeric literals\n\nIn accordance with Java 8 specification, Kotlin supports now numeric literals with single underscore symbols between digits. For example:\n\n```kotlin\nval ONE_MILLION = 1_000_000\n```\n\nSee the [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/underscores-in-numeric-literals.md) for more details and examples.\n\n## Generic Enum values access\n\nThe support of the [proposal](https://github.com/Kotlin/KEEP/blob/master/proposals/generic-values-and-valueof-for-enums.md) is landed to the standard library in a form of two intrinsic functions:\n\n```kotlin\ninline fun > enumValues(): Array\ninline fun > enumValueOf(name: String): T\n```\n\nThey allow to enumerate the values of a generic enum type. E.g.\n\n```kotlin\nenum class RGB { RED, GREEN, BLUE }\n\nprint(enumValues().joinToString { it.name }) // prints RED, GREEN, BLUE\n```\n\n## Scope control for builder-like DSLs\n\nAs described in details in the [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/scope-control-for-implicit-receivers.md), DSL authors had problems in expressing scope restrictions for builder-like constructs. E.g., for some html-builder DSL:\n\n```kotlin\ntable {\n tr {\n tr {} // PROBLEM: Table.tr() is valid here\n }\n}\n```\n\nTo solve the problem we added the `@DslMarker` annotation that allows to control visibility scope in these cases more precisely. For usage example see [preview version of kotlinx.html library using this feature](https://github.com/Kotlin/kotlinx.html/tree/dsl-markers) (see [HtmlTagMarker](https://github.com/Kotlin/kotlinx.html/blob/dsl-markers/shared/src/main/kotlin/api.kt#L103) and [HTMLTag](https://github.com/Kotlin/kotlinx.html/blob/dsl-markers/shared/src/main/kotlin/htmltag.kt#L5) implementations and [DSL-markers.md](https://github.com/Kotlin/kotlinx.html/blob/dsl-markers/DSL-markers.md) for the preview library usage info).\n\n## Standard library unification\n\nThe standard library unification process for different platforms is moving forward. We have started unifying exception types in 1.1-M2 and now some more common types, which are supported on all platforms, are available in `kotlin.*` packages, and are imported by default. These include:\n\n* `ArrayList`, `HashSet`, `LinkedHashSet`, `HashMap`, `LinkedHashMap` in `kotlin.collections`\n* `Appendable` and `StringBuilder` in `kotlin.text`\n* `Comparator` in `kotlin.comparisons`\n\nOn JVM these are just typealiases of the good old types from `java.util` and `java.lang`\n\n## New language features support in the JavaScript backend\nn\nJavaScript backend now supports the following Kotlin language features on par with JVM backend:\n\n* Coroutines\n* Destructuring in lambda parameters\n* Unused variable name in destructuring declaration\n\n## JS code generation improvements\n\nJavaScript backend now generates more statically checkable code, which is friendlier to JS code processing tools, like minifiers, optimisers, linters, etc.\n\n## How to Try It\n\n**In Maven/Gradle:** Add [http://dl.bintray.com/kotlin/kotlin-eap-1.1](http://dl.bintray.com/kotlin/kotlin-eap-1.1) as a repository for the build script and your projects; use 1.1-M03 as the version number for the compiler and the standard library.\n\n**In IntelliJ IDEA:** Go to _Tools → Kotlin → Configure Kotlin Plugin Updates_, then select “Early Access Preview 1.1” in the _Update channel_ drop-down list, then press _Check for updates_.\n\nDrive to Kotlin!\n\n","author":"Ilya Chernikov","date":"2016-11-24","type":"article","categories":["Kotlin"],"features":["highlightjs"],"description":"","filename":"","lang":"EN","enclosure":null},{"title":"Getting Started with Kotlin and Anko on Android","url":"https://realm.io/news/getting-started-with-kotlin-and-anko/","body":"\nby [Donn Felker](https://twitter.com/donnfelker)\n\n### Getting Started With Kotlin and Anko on Android\n\nI’m just going to say it like it is ...\n\n> Android is stuck in Java 6 purgatory.\n\n![ADB Hell](http://cl.ly/2q0e3B3l202Z/1__adb.png)\n\nWhen I first started developing for Android, I was coming out of working very heavily with C# for a few years. I came over to find a lack of proper generics support (when compared to Java generics), no lambda expressions, and an awkward syntax for common things that I felt should just be in the language. 8 years later, I’m still stuck writing super-verbose Java 6. Java 8 has been out for a while now, and it would be great to use some of those features without having to resort to bytecode weaving! (That said, I am very thankful for [retrolambda](https://github.com/orfjackal/retrolambda).) Unfortunately, who knows if or when Java 8 support will ever arrive.\n\nThankfully, there seems to be a new hope for Android development: [Kotlin](https://kotlinlang.org).\n\n![Kotlin Logo](http://cl.ly/0q2n240R3I3N/kotlin-logo.png)\n\nKotlin is a new JVM-compatible language from JetBrains that you can use to write Android applications. If you haven’t been exposed to the language, I highly recommend that you watch [Michael Pardo’s talk on Kotlin](https://realm.io/news/droidcon-michael-pardo-kotlin/) from [Droidcon NYC](http://droidcon.nyc). Furthermore, the layout view for a portion of the application will be created with [Anko](https://github.com/Kotlin/anko), a DSL (Domain-Specific Language) for Android which is written in Kotlin. You can get a basic understanding of Anko [here](https://github.com/Kotlin/anko).\n\nKotlin, as a language, is a breath of fresh air compared to Java 6. Once you get used to the syntax, you will notice that it is much more succinct than its Java 6 counterpart. Since Kotlin is JVM-compatible, it will compile down to JVM bytecode that is understood by Android.\n\n_**Important**: This article will assume that you have a basic understanding of Kotlin and Anko._\n\n### Using Kotlin in an Android project\n\nAs with anything new, you’d probably like to try out Kotlin but you don’t want to commit an entire project to it just yet. With Kotlin and Android Studio, you can have both Java and Kotlin sitting side by side in your application. I recommend taking a screen, a feature, or a simple custom widget, and writing it in Kotlin to see how it feels. Integrating Kotlin into your codebase slowly allows you to give the language a test run and allows you to keep existing application code untouched.\n\nThankfully it’s quite easily to integrate Kotlin into an existing Android application with the free Kotlin plugin for Android Studio. To get started, you’ll need to install the plugin. Open Android Studio and select `Configure > Plugins`. If the screen below is not visible, close all your projects and `Welcome to Android Studio` window will present itself.\n\n![Configure Plugin](http://f.cl.ly/items/0h2Q0f0I3g471m3j190s/Screen%20Shot%202016-03-01%20at%2010.45.09%20AM.png)\n\nThen select `Install JetBrains Plugin` as shown below.\n\n![Install Plugin](http://cl.ly/312E3M123n2L/3_1_16__10_46_AM.png)\n\nNow search for `Kotlin` and install the `Kotlin` plugin as shown below. The main Kotlin plugin includes the Android extensions.\n\n![](http://cl.ly/2I1k3H0X2i0o/Untitled-1___100___Layer_1__RGB_8____.png)\n\nYou’re now ready to start building your first feature with Kotlin!\n\n### The Application\n\nThe application that I’m going to be working with is a simple to-do list application. The main screen has a list of to-dos that looks like this:\n\n![Example Screenshot](http://cl.ly/2t15210V3r3l/3_1_16__11_05_AM.png)\n\nTo add a to-do, users tap on the FAB (Floating Action Button). To edit a to-do, they tap on the to-do itself. This will load the add/edit screen. The add/edit screen is what I will write in Kotlin and Anko.\n\n### What is Anko?\n\n[Anko](https://github.com/Kotlin/anko) is a DSL (Domain-Specific Language) for Android written in Kotlin. Traditionally, Android views are expressed as XML layouts. This XML is usually duplicated in various parts of your application and is not re-used (sometimes it is, with includes). At runtime, the XML is then transformed into the Java representation of the view which wastes CPU and battery. Anko allows you to write this view in Kotlin, in an Activity or Fragment (or even as an [AnkoComponent](https://github.com/Kotlin/anko#ankocomponent), an external Kotlin file that represents the view).\n\nHere’s an example of a simple XML file that is transformed to Anko.\n\n**XML**\n\n```xml\n\n\n \n\n \n \n\n\n```\n\n**The same view expressed in Anko**\n\n\n```kotlin\nverticalLayout {\n var title = editText {\n id = R.id.todo_title\n hintResource = R.string.title_hint\n }\n button {\n textResource = R.string.add_todo\n onClick { view -> {\n // do something here\n title.text = \"Foo\"\n }\n }\n }\n}\n```\n\nNotice the inline click listener in the layout definition above. Since this is Kotlin, you can also access other view members, such as `title` and use them in the click listener.\n\n### Getting Started\n\nUsing this [starter app](https://github.com/donnfelker/KotlinMix/archive/fresh.zip) you can start with a blank slate. (Final code is available [here](https://github.com/donnfelker/KotlinMix/)). This app has the following:\n\n* An Activity (`MainActivity`) that acts as a simple controller of the application.\n* A [RecyclerView](https://github.com/thorbenprimke/realm-recyclerview) to show the to-dos on the first screen (TodosFragment)\n* A Realm database to store the to-dos\n* A `Todo.java` Realm model\n* An adapter for the RecyclerView\n\nYou will now build the add/edit screen using Kotlin and Anko.\n\n### Set Up Your Application for Kotlin and Anko\n\nNow that you have the Kotlin extension installed, you’ll want to configure your application using the `Configure Kotlin in Project` action. In Android Studio, press `CMD+SHIFT+A` to open the action finder window. Type in `Kotlin` and select `Configure Kotlin in Project` action as shown below:\n\n![Actions](http://cl.ly/2f023X2q1r2r/Screenshot_3_1_16__11_57_AM.png)\n\nAfter this runs, your `build.gradle` file will have been updated with `kotlin-android` applied at the top of the file, a Kotlin `sourceSet` added, and Kotlin added to your dependencies.\n\nDuring this time you’ll also want to add Anko to your dependencies. Your `build.gradle` file should look similar to this:\n\n\n```groovy\napply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\n\nandroid {\n compileSdkVersion 23\n buildToolsVersion \"23.0.2\"\n\n defaultConfig {\n applicationId \"com.donnfelker.kotlinmix\"\n minSdkVersion 16\n targetSdkVersion 23\n versionCode 1\n versionName \"1.0\"\n }\n buildTypes {\n release {\n minifyEnabled false\n }\n }\n packagingOptions {\n exclude 'META-INF/services/javax.annotation.processing.Processor'\n }\n sourceSets {\n main.java.srcDirs += 'src/main/kotlin'\n }\n}\n\ndependencies {\n compile fileTree(dir: 'libs', include: ['*.jar'])\n testCompile 'junit:junit:4.12'\n\n // Kotlin\n compile \"org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version\"\n\n // Anko\n compile 'org.jetbrains.anko:anko-sdk15:0.8.2' // sdk19, sdk21, sdk23 are also available\n compile 'org.jetbrains.anko:anko-support-v4:0.8.2' // In case you need support-v4 bindings\n compile 'org.jetbrains.anko:anko-appcompat-v7:0.8.2' // For appcompat-v7 bindings\n\n compile 'com.android.support:appcompat-v7:23.1.1'\n compile 'com.android.support:design:23.1.1'\n compile 'io.realm:realm-android:0.87.1'\n compile 'com.github.thorbenprimke:realm-recyclerview:0.9.12'\n compile 'com.jakewharton:butterknife:7.0.1'\n compile 'com.android.support:support-v4:23.1.1'\n}\nbuildscript {\n ext.kotlin_version = '1.0.0'\n repositories {\n mavenCentral()\n }\n dependencies {\n classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n }\n}\nrepositories {\n mavenCentral()\n}\n```\n\nYou’re now ready to start creating the add/edit to-do screen.\n\n### Adding a Fragment with Kotlin\n\nIf the `src/main/kotlin/com.donnfelker.kotlinmix/` directory does not exist, create it. You’ll notice that the `kotlin` folder turns blue indicating that this is a source folder.\n\nRight-click on the `/src/main/kotlin/com.donnfelker.kotlinmix/` folder, select `New > Kotlin File/Class`, and give it the name `EditFragment`. The new file is created and only contains a package declaration.\n\nCopy the code below and past it into the `EditFragment` file.\n\n```kotlin\npackage com.donnfelker.kotlinmix\n\nimport android.os.Bundle\nimport android.support.v4.app.Fragment\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.Button\nimport android.widget.EditText\nimport com.donnfelker.kotlinmix.models.Todo\nimport io.realm.Realm\nimport org.jetbrains.anko.*\nimport org.jetbrains.anko.support.v4.UI\nimport org.jetbrains.anko.support.v4.find\nimport java.util.*\n\nclass EditFragment : Fragment() {\n\n val TODO_ID_KEY: String = \"todo_id_key\"\n\n val realm: Realm = Realm.getDefaultInstance()\n\n var todo: Todo? = null\n\n companion object {\n fun newInstance(id: String): EditFragment {\n var args: Bundle = Bundle()\n args.putString(\"todo_id_key\", id)\n var editFragment: EditFragment = newInstance()\n editFragment.arguments = args\n return editFragment\n }\n\n fun newInstance(): EditFragment {\n return EditFragment()\n }\n }\n\n override fun onActivityCreated(savedInstanceState: Bundle?) {\n super.onActivityCreated(savedInstanceState)\n\n if(arguments != null && arguments.containsKey(TODO_ID_KEY)) {\n val todoId = arguments.getString(TODO_ID_KEY)\n todo = realm.where(Todo::class.java).equalTo(\"id\", todoId).findFirst()\n val todoTitle = find(R.id.todo_title)\n todoTitle.setText(todo?.title)\n val todoDesc = find(R.id.todo_desc)\n todoDesc.setText(todo?.description)\n val add = find