company_banner

Веб-редактор кода на Kotlin, с примерами и компиляцией в JavaScript

    Слышали про Kotlin? Это новый JVM-ориентированный язык программирования от JetBrains?

    До вчерашнего дня о Kotlin можно было только почитать и пофантазировать.
    А вчера команда разрабатывающая язык открыла для всеобщего доступа web-редактор кода на Kotlin c возможностью компиляции и запуска. Добро пожаловать на http://kotlin-demo.jetbrains.com!

    Вот, что можно сделать сейчас:
    • Поиграться с готовыми примерами и задачками.
    • Запустить ваш код на JVM, работающей на нашем сервере. Т.е. можно использовать знакомые вам классы из JDK.
    • Также можно скомпилировать Kotlin-код в JavaScript и запустить его в браузере

    Редактор кода уже сейчас умеет делать подсветку ошибок «на лету» либо в момент запуска (по умолчанию), форматирование кода и предоставляет автодополнение по Ctrl+Space.
    Kotlin web demo
    Проект находится в стадии разработки и будет активно развиваться. Дальше обещается библиотека для более удобной работы с расширениями JDK типа collections и пр., больше примеров и интересных задач.

    Ваши идеи, толковые предложения, а также отчеты об ошибках очень приветствуются в баг-трекере проекта.

    А если есть желание посоревноваться и получить приз, то предлагаем вот такие 2 задачки:

    1) Дана строка, найти в ней самое длинное слово. Словом считается последовательность латинских букв, ограниченная границами строки или символами, не являющимися латинскими буквами.
    2) Число в римской записи перевести в десятичную.

    Публикуйте ссылки на код (через gist например) в комментариях. Авторы первых правильных решений получат футболку с логотипом Kotlin от нас.

    Удачи!
    JetBrains 177,46
    Делаем эффективные инструменты для разработчиков
    Поделиться публикацией
    Похожие публикации
    Комментарии 51
    • +3
      JetBrains красавцы, супер. Пошел смотреть.
      • 0
        Да, действительно класно выглядит, но нашел багу

        не работает выделени по словам ctrl + shiwt + arrow right / arrow left.

        Win 7, Chrome
      • 0
        Как на маке вызвать автодополнение? Cmd+Space переключает раскладку, Ctrl+Space ничего не дает.
        • 0
          Авто дополнение пока не сильно помогает.
          • 0
            У меня Ctrl + Space работает.
            • 0
              Ctrl+Space работает и на Маке. Только что проверено в Safari, Firefox и Chrome. А что за браузер?
              • 0
                Проверьте, что вы переключились с «No highlighting» на Server или Client.
                • +1
                  Переключился. Теперь при нажатии все виснет. Видимо, это значит, что все идет так, как должно.
                  • 0
                    Переключились в какой режим?
                    Виснет что? Браузер? Редактор?
                    Какой браузер?
                    • 0
                      Переключился в клиента, дал разрешение на выполнение жабы, виснет редактор. Хром, вроде последний.
                      • 0
                        Может, просто долго грузит апплет? Он довольно большой пока
              • –1
                Первая задача
                pastebin.com/fB0EQKrE
              • 0
                3  fun main(args : Array<String>) {
                4    var map = java.util.HashMap<Int, Int>()
                5    map.put(0, 2)
                6  }
                

                Exception in thread "main" java.lang.NullPointerException
                at multiplier.namespace.main(dummy.jet:5)

                • 0
                  Упс, рано отправил. Вопрос: Что я делаю не так?
                  • 0
                    Баг, спасибо. Сгенерированный байткод пытается выполнить unboxing значения, которое вернул put. Которое, что неудивительно, null. Вывод — HashMap для не работает для типов значений, которые приводятся к java primitives
                    • 0
                      Не очень понял ваше объяснение. Тогда почему дохнет с тем же исключением следующий код:
                      fun main(args : Array<String>) {
                        var map = java.util.TreeMap<Int, Int>
                        var value : Int? = map.get(0)
                      }
                      
                      • 0
                        По той же причине. Кривые руки делают ненужный unbox. Вот что генерируется в вашем случае:
                            NEW java/util/TreeMap
                            DUP
                            INVOKESPECIAL java/util/TreeMap.<init> ()V
                            ASTORE 1
                            ALOAD 1
                            ICONST_0
                            INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
                            INVOKEVIRTUAL java/util/TreeMap.get (Ljava/lang/Object;)Ljava/lang/Object;
                            CHECKCAST java/lang/Number
                        /* Проблема здесь */ INVOKEVIRTUAL java/lang/Number.intValue ()I
                            INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
                            ASTORE 2
                        
                        • 0
                          Мда, печаль. Ну и ещё один баг тогда:

                          fun main(args : Array<String>) {
                            var map = java.util.TreeMap<Int, Int>
                            for(entry in map.entrySet()) {
                              //...
                            }
                          }
                          


                          Даже не компилируется. Говорят, что разработчикам сообщено, но я продублирую на всякий:
                          Exception in Kotlin compiler: a bug was reported to developers.
                          java.lang.IllegalStateException: org.jetbrains.jet.codegen.CompilationException: should not compile an error type
                          at org.jetbrains.jet.codegen.CompilationErrorHandler$1.reportException(CompilationErrorHandler.java:11)
                          at org.jetbrains.jet.codegen.GenerationState.compileCorrectFiles(GenerationState.java:121)
                          at org.jetbrains.jet.codegen.GenerationState.compileCorrectFiles(GenerationState.java:109)
                          at web.view.ukhorskaya.responseHelpers.CompileAndRunExecutor.getResult(CompileAndRunExecutor.java:74)
                          at web.view.ukhorskaya.sessions.HttpSession.sendExecutorResult(HttpSession.java:283)
                          at web.view.ukhorskaya.sessions.HttpSession.handle(HttpSession.java:59)
                          at web.view.ukhorskaya.handlers.ServerHandler.handle(ServerHandler.java:116)
                          at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
                          at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:65)
                          at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:68)
                          at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:554)
                          at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
                          at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:526)
                          at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                          at java.lang.Thread.run(Thread.java:662)
                          Caused by: org.jetbrains.jet.codegen.CompilationException: should not compile an error type
                          at org.jetbrains.jet.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:141)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.gen(ExpressionCodegen.java:146)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.generateBlock(ExpressionCodegen.java:776)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.visitBlockExpression(ExpressionCodegen.java:674)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.visitBlockExpression(ExpressionCodegen.java:42)
                          at org.jetbrains.jet.lang.psi.JetBlockExpression.accept(JetBlockExpression.java:24)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:135)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.gen(ExpressionCodegen.java:146)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.returnExpression(ExpressionCodegen.java:854)
                          at org.jetbrains.jet.codegen.FunctionCodegen.generatedMethod(FunctionCodegen.java:200)
                          at org.jetbrains.jet.codegen.FunctionCodegen.generateMethod(FunctionCodegen.java:53)
                          at org.jetbrains.jet.codegen.FunctionCodegen.gen(FunctionCodegen.java:46)
                          at org.jetbrains.jet.codegen.NamespaceCodegen.generate(NamespaceCodegen.java:66)
                          at org.jetbrains.jet.codegen.GenerationState.generateNamespace(GenerationState.java:137)
                          at org.jetbrains.jet.codegen.GenerationState.compileCorrectFiles(GenerationState.java:118)
                          ... 14 more
                          Caused by: java.lang.IllegalStateException: should not compile an error type
                          at org.jetbrains.jet.codegen.JetTypeMapper.mapType(JetTypeMapper.java:295)
                          at org.jetbrains.jet.codegen.JetTypeMapper.mapType(JetTypeMapper.java:283)
                          at org.jetbrains.jet.codegen.JetTypeMapper.mapType(JetTypeMapper.java:275)
                          at org.jetbrains.jet.codegen.JetTypeMapper.mapType(JetTypeMapper.java:271)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.asmType(ExpressionCodegen.java:181)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.generateForInIterable(ExpressionCodegen.java:346)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.visitForExpression(ExpressionCodegen.java:319)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.visitForExpression(ExpressionCodegen.java:42)
                          at org.jetbrains.jet.lang.psi.JetForExpression.accept(JetForExpression.java:23)
                          at org.jetbrains.jet.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:135)
                          ... 28 more
                          • +3
                            Ааа, как я адски засрал страничку размашистым стектрейсом. Сорри :)
                      • 0
                        При учёте того, что литералы не умеют бокситься в стандартные java-обёртки для примитивов, получается, что для того, чтобы, например, увеличить на 1 целочисленное значение в отображении, приходится писать такой ужас?

                        fun <K> Map<K, Integer>.increment(key : K) {
                          var count : Integer? = get(key)
                          put(key, if(count == null) Integer(1) else Integer(count?.intValue()?.plus(1).sure()))
                        }
                        
                  • –1
                    Первая задача
                    pastebin.com/wr3uV7TX
                    • –1
                      Вторая задача
                      pastebin.com/xjxxj2AC
                      • 0
                        Спасибо за решение! Но, к сожалению, неправильно декодируется число MDCCCCLXXXXVIIII (1999)
                        • 0
                          Спасибо (пофиксил pastebin.com/xjxxj2AC)
                          мда, поспешил — протупил
                          • 0
                            Вообще-то, с XIX века 1999 — это MCMXCIX…
                        • 0
                          Спасибо за решение! Но, к сожалению, неправильно обработана пустая строка.
                          • 0
                            Спасибо

                            А почему бы вам не скооперироваться с каким нибудь ресурсом типа codeforces.ru? — получили бы бОльший фидбэк ;)

                            P.S. решение пофиксил pastebin.com/dFZn4cBz
                        • 0
                          По-моему, упал сервер :(
                          • 0
                            Очень здорово!

                            Вначале хотел спросить, зачем System.out?.println вызывается через safe-call, если out вроде как не может быть null, но поигравшись с компилятором понял, почему так. Тогда вопрос другой, а вообще есть ли возможность для референс типов вызывать методы по старому, без safe-call (настройки компилятора, или что-то в этом духе)? Есть ощущение, что далеко не всегда это необходимо, а код вопросы могут засорить основательно.
                            • 0
                              Тоже это настораживает. Если компилятору нужны эти вопросы и нет возможности отключить эти проверки, то пусть автодополнение само их ставит. Например, пишу «System.out», ставлю точку получаю «System.out?.» в этот момент я просто подумаю «ага может быть null, ну да ладно».
                            • +1
                              Эх, опять haxe клонируют. Поздно правда. :)
                              • 0
                                haxe теперь поддерживает компиляцию во flash, ios, android, c++, c#, java (скоро), javascript.
                                • 0
                                  Но раз от jetbrains, то вещь однозначная сильная. Как я понимаю скоро будет десктопная версия. Жаль только платная.
                                  • 0
                                    Обещали компилер бесплатно.
                                    И плагины для идеи и клипца.
                                    • 0
                                      Радует. Но все равно мой выбор пока за haxe.
                              • 0
                                Всё-таки — «Kotlin»?
                                • +1
                                  Не хватает split… Лень писать.
                                  • 0
                                    Первая задача: gist.github.com/1596794 Угадывание синтаксиса и API по неформальной документации — то ещё удовольствие, я вам скажу…

                                    А почему String не совпадает с java.lang.String хотя бы по методам и приходится его так уродливо кастить?
                                    • +1
                                      Первое и второе.
                                      И не нужно говорить, что сначала разбивать строку, а потом искать самую длинную — медленно. Думаю, что создатели конкурса хотели увидеть не «напишу всё так же, как писал на java», а скорее «воспользуюсь-ка я новыми возможностями».

                                      А ещё я три бага зарепортил, один из них оказался критичным, остальные пока не знаю. Дайте мне футболку и клёвые магнитики :)
                                      • 0
                                        Спасибо за участие и за баги!
                                        В первой задаче неправильно обрабатывается строка «1».
                                        А вторая решена правильно. Поздравляем!
                                      • 0
                                        Первая:
                                        raw.github.com/mir-nomer-nol/Kotlin/master/longString

                                        Натолкнулся на невозможность итерироваться по строке через for (c in str) {}
                                        • +1
                                          Возможность итерироваться появится если добавить в свой код следующий кусок:
                                          class StringIterator(val s : String){
                                            inline fun next() = if (i < s.length) s[i++] else throw NoSuchElementException()
                                            inline fun hasNext() = i < s.length
                                            private var i = 0
                                          }
                                           
                                          inline fun String.iterator() = StringIterator(this)
                                          
                                          • 0
                                            спасибо. Было бы очень здорово, если бы это было отражено в доке… А то сходу непонятно
                                            • 0
                                              В доке написано что по стрингу можно итерироваться, но пока не работает(соответствующий баг есть)
                                          • 0
                                            Первая: pastebin.com/CvGzyB8c
                                            Вторая: pastebin.com/WY0i8Nqt

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                          Самое читаемое