Java на habrahabr
JAVA / [Перевод] Scala хуже, чем Java. Как минимум, для половины Java проектов
Итак, в своем посте (прим.пер. Да, Вирджиния, Scala сложна!) я согласился с тем, что Scala слишком сложна для большей части Java разработчиков. Тот пост вызвал немало дискуссий, большая часть которых исказила его смысл. Теперь я пишу снова, надеясь пояснить, о чем я, собственно, говорил и зачем мне все это нужно.
Но сначала обо мне. Меня зовут Дэвид Поллак.
Блог о программировании
Поездка в Санкт-Петербург
Прошло уже больше месяца, с тех пор как я обещал друзьям написать про свою поездку в Питер. Было очень много разных дел по работе, в итоге только сейчас смог дописать.
Как все было.
Где-то месяц назад, совершенно случайно, увидел объявление, что 1 октября в Питере будет проводиться Scala Day.
Решил зарегистрироваться, хотя вероятность поездки была очень мала - было много дел по работе. В конечном итоге поехать удалось, но полноценно побывать на Scala Day у меня не получилось. Буквально заглянул меньше чем на час.
Для тех кто не в курсе - Scala это такой язык программирования, очень мощный и интересный. За последние несколько лет мне удалось "заразить" программированием на Scala моих многих знакомых и друзей. Мы время от времени организуем небольшие встречи-семинары-тусовки, о которых возможно расскажу позднее.
Итак, про поездку.
Стояла отличная осенняя погода.
Начитавшись страшных отзывов про трассу Москва-Санкт-Петербург, я решил поехать не сразу в Питер, а заехать по дороге в Великий Новгород.
Во-первых всегда было интересно побывать в этом городе, а во-вторых хотелось нормально отдохнуть после дороги и приехать в Питер свежим с утра.
Фото из Великого Новгорода
Великий Новгород понравился, если получится советую там побывать.
Что касается автомагистрали. Нельзя сказать, что она вся такая страшная и убитая. Я ожидал намного хуже. Конечно были довольно скверные отрезки, но были и участки с хорошим покрытием. Также было видно, что дорогой занимаются, в некоторых местах ведутся ремонтные работы, что уже очень хорошо.
Так что в целом, дорогой я доволен и обратный путь мы проделали за один раз - выехали из Питера ранним утром, к вечеру уже были дома.
Плохая дорога
Нормальная дорога
Про проживание в Санкт-Петербурге - остановились в мини-отеле. Стоимость ночлега не большая - 2000 руб за ночь. Номер вполне приличный.
Правда мне показалось, что там немного холодно и сыро и я кажется немного простыл (возможно дело не в отеле... у меня так каждый раз, когда приезжаю в Санкт-Петербург - простываю).
Машину на ночь пришлось оставить на Литейном, потом нашел платную парковку.
Конечно был культурный шок от двора...
Про Scala встречу.
Место проведения Scala встречи ("БИ Ингрия") нашел довольно просто. БИ - оказывается означает Бизнес-Инкубатор. Несмотря на зловещее название, оказалось, что это обычное здание и с добродушным охранником, который объяснил куда идти.
БИ ИНГРИЯ
Я пришел где-то на час позже начала, в аудитории было очень много людей, многие стояли вдоль стенок.
Пересказывать все, что было смысла не вижу, т.к. можно посмотреть видео здесь: http://www.e-legion.ru/blog/
Вот пару фотографий:
Scala программисты
Все лекции снимались на видеокамеру
Лично меня заинтересовал Scala PlugIn для IDEA. Думаю это вообще самая болевая точка для Scala-сообщества - нормальный редактор для Scala.
В целом само мероприятие было интересным, довольно многолюдным (в хорошем плане), с кофе-брейком и нормальным WiFi-ем (не то, что на GDD2011).
Кстати про WiFi и интернет. Пока лекторы (разработчики IDEA) в самом начале объясняли "зачем нужен нормальное IDE для Scala", мне за это время удалось скачать IDEA вместе со Scala-плагином и потом, в почти синхронном режиме, повторять демонстрацию. Правда почему-то у меня не всё получилось,
как будет время - попробую разобраться.
К сожалению, у меня был всего один свободный день, а город посмотреть очень хотелось (до этого был в Питере еще студентом, когда приезжал к друзьям в гости на пару дней, да и то тогда в основном пьянствовали...). В итоге пришлось позорно сбежать со Scala Day, о чем конечно же сожалею.
Зато немного успел погулять по Питеру. Вот фото с Исаакиевского Собора:
фотка Санкт-Петербурга
Java на habrahabr
JAVA / Akka для Java разработчика (часть 1)
В последнее время появилось довольно много языков программирования, которые используют для JVM как платформу для выполнения. Одним из наиболее «горячих» тем для обсуждения в последнее время является Scala. В этой статье я не буду рассматривать заслуженно это или нет, просто хочу рассказать как можно использовать средства этого языка используя Java и не написав ни одной строчки на Scala.
Блог о программировании
Мои хинты для Netbeans 7
Недавно нужно было заново установить Netbeans 7.
Вот некоторые действия, которые всегда приходится делать после установки "коробочной" версии,
а именно: поддержка Scala, интерфейс на английском и quick file chooser.
Установка
Заходим на официальный сайт: netbeans.org
Нажимаем на [Download FREE] и переходим на ссылку http://netbeans.org/downloads/index.html
Скачиваем, устанавливаем и запускаем.
Итак, что приходится делать:
0. Обновления.
На всякий случай проверить наличие обновлений:
Меню → Help → Check for Updates
1. Русский → English
Чтобы вернуть обратно английский нужно:
- Найти файл "netbeans.conf" (для Windows-пользователей: он должен находится где-то здесь - "C:\Program Files\NetBeans 7.0\etc\" )
- Указать в настройках --locale en_US
2. File Chooser
Сразу же установить плагин Quick File Chooser:
Меню → Тools → Plugins → Available Plugins
Это намного более шустрый и удобный (на мой взгляд) диалог для выбора файлов.
3. Scala
Ставим plugin для работы со Scala.
Для версии 2.8.x: http://plugins.netbeans.org/plugin/36598/nbscala-2-8-x
Подробнее можно прочитать на вики нетбинсов:
http://wiki.netbeans.org/Scala
или на портале с плагинами:
http://plugins.netbeans.org/
Теги:
Java
3. Инструментарий
Scala
netbeans
Блог о программировании
Scala и пустота
Scala и пустота
В Scala есть несколько разных сущностей для обозначения несуществующих, пустых или неопределенных объектов.
Начнем с самого привычного для Java-программистов случая.
Null
Null – это trait. Объект null (с маленькой буквы) — это как раз и есть объект типа Null. Он находится внизу иерархии типов в Scala, в противовес AnyRef.
Благодаря этому вы всегда можете как-бы "занулить" любую ссылку, т.е. присвоить ссылки значение null:
Null работает только для ссылочных типов, для более общего случая, есть "ничто (Nothing)" .
Nothing
Nothing – это тоже trait. Nothing находится на самом дне иерархии типов, в противовес Any. Соответственно, это более общий тип, чем Null и подходит даже для AnyVal объектов (числа, буквы, правда/ложь и т.д.).
В отличие от Null, Nothing не может иметь экземпляров (на то оно и ничто).
Другими словами нет аналога null для Nothing.
Возникает вопрос, где такое самое "нижнее ничто" может использоваться?
В документации по API можно найти несколько примеров:
Этот метод никогда ничего не возвращает, поэтому возвращаемый тип Nothing.
Unit
Тип Unit – чем-то похоже на void, который исползуется в Java. В Scala тип Unit используем тогда, когда хотим показать, что функция возвращает пустое значение (но все-таки что-то возвращает, хоть и пустое).
Если открыть документацию, то можно увидеть что:
class Unit extends Any with AnyValВнимание! AnyVal, а не AnyRef. Это значит, что Unit это не ссылочный тип ( в отличие от Null). Можно сказать, что Unit-у как бы "ближе по родству" будут числа, буквы и другие примитивные типы (которые тоже AnyVal).
В отличие от Nothing, Unit повезло больше. Он может иметь свой объект, правда в единственном экземпляре. Он обозначается двумя круглыми скобками: (). Например:
scala> val u = () u: Unit = ()Другими словами Nothing уместен тогда, когда функция в принципе ничего не возвращает, а Unit – это когда возвращает, но оно пустое.
Это отличие существенно. Например результат вызова функции с Unit может быть присвоено (в Java с void такой фокус не выйдет).
Nil
Nil – пустой список (extends List[Nothing]).
Поскольку Nil – это список, хоть и пустой, у него как у любого списка есть метод :: (два двоеточия), с помощью которого удобно создавать списки:
Это возможно благодаря тому, что название метода заканчивается на : (двоеточие), в таком случае метод применяется к правому операнду (работает для операторной нотации вызова метода).
Другими словами, это аналогично вызову: (Nil.::(2)).::(1)
None
None – это такой хитрый объект, который используется в случае, если мы хотим получить что-то, например, из Map, а его там нет.
Например:
scala> var m = Map(1->2) m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2) scala> val n = m.get(100)// ну нет такого элемента n: Option[Int] = NoneNone примечателен тем, что:
- это объект (т.е. синглтон)
- это кейс-объект
- наследуется от Option[Nothing]
В случае попытки получить значение (вызвав метод n.get()), мы получим исключение:java.util.NoSuchElementException.
Если у None вызывать метод isEmpty() – мы получим true.
Поскольку None – объект кейс-класса, то мы можем его "матчить" (сопоставлять по шаблону).
scala> n match { case Some(x) => println("x:" + x) case None => println("none") }Если у None вызвать метод toList – мы получим пустой список (т.е. Nil).
scala> n.toList() == Nil res21: Boolean = trueПоскольку None объявлен как extends Option[Nothing], а Nothing – "самое нижнее ничто", то None может работать с любыми типами (как с ссылочными так и с примитивными).
Теги:
Программирование
Scala
Блог о программировании
Main args, netbeans
Пара простых вещей (про Java/Scala + CLI и NetBeans)
Самый популярный и набивший оскомину пример HelloWorld встречается, наверное, уже во всех учебниках по программированию:
Здесь String[] args — аргументы командной строки.
Например:
java HelloWorldApp 1 2 означает, что args будет равно {"1", "2"}.
Если передается всего один аргумент (например, "debug"), то все очень просто — можно подсмотреть пример из туториала: cmdLineArgs.
В случае, если аргументов много (как в гнусных линуксовых командах), то можно использовать какую-нибудь готовую библиотеку:
Для большинства задач их вполне достаточно. В том случае, если хочется большего разнообразия, то можно посмотреть здесь или в поисковиках.
В том случае, если аргументы не такие сложные и не слишком простые, а что-то среднее, то тянуть для этих целей дополнительную библиотеку нет никакого смысла. Например, если нужно передать что-то вроде: "-x -size 1024 -v". Обычно это бывает, когда требуется небольшая, почти "одноразовая" программа...
Многие настолько не любят писать разбор таких аргументов, что лепят все параметры в системные свойства (java ... -Dfoo="some string"), чтобы потом дергать их через System.getProperty().
Это конечно удобно, но не всегда нормально.
Проще написать разбор обычными стандартными средствами:
В Scala все то же самое.
Тривиальный случай – делаем как в примере на официальном сайте: Snippet: Match Arguments.
Что-то очень сложное – подключаем сторонние библиотеки (ту же апачевскую или jopt), что и в Java случае.
В том случае, если что-то среднее, то можно написать на чистой Scala:
Про другую известную многим фишку, о которой хотел рассказать — макросы в NetBeans-ах.
Точнее, про самый популярный макрос - debug-var. Вызывается по нажатию: Ctrl-J D.
Вообще макросы в нетбинсах есть уже много лет, по-крайне мере, когда я только начинал использовать нетбинс (3.* версии), они уже там были.
Например, для Scala можно сделать макрос, который будет вставлять в код: println("var=" + var)
Настроить можно здесь:
Tools -> Option -> Editor -> Macros
Про другие полезные макросы можно почитать здесь
Теги:
Java
4. Полезняшки
Scala
netbeans
Блог о программировании
Немного карри
Использовать карринг в Scala одно удовольствие.
Само определение каррирования(или карринга, названо в честь Хаскелла Карри):
Для функции h типа h : (A × B) → C оператор каррирования Λ выполняет преобразование
Λ(h) : A → (B → C)
Отметим, что Λ - это оператор, то есть "функция над функциями".
Например берем функцию foo(x,y), каррируем и получаем moo(x)(y) - функцию от x которая возвращает функцию от y.
Таким образом мы можем сводим программу к вычислению функции от одного аргумента.
Чтобы выполнить карирование, можно вызвать Function.curried. Сейчас это уже устаревший метод, т.к. curried можно вызывать сразу у функции.
Небольшой пример (для наглядности в императивном стиле):
scala> val foo = (x:Int,y:Int) => x + y // функция от 2(ДВУХ) аргументов x и y. scala> foo(1,2) // просто сложили и получили три scala> val moo = foo.curried // получили функцию от 1(ОДНОГО) аргумента, которая возвращает scala> val zoo = moo(1) // функцию от 1(ОДНОГО) аргумента scala> zoo(2) // урраа! получили три scala> // можно каррировать и так: scala> def noo(x:Int, y:Int) = x * y scala> val a = noo _ // получили функцию от 2-х аргументов (подробнее см. partially applied function) scala> val b = a.curried scala> b(2) // = фунция 2 * аргумент scala> b(2)(3) // = 6Метод curried можно найти в трейтах начиная от Function2 и заканчивая Function22.
Это значит, что вы можете использовать его для функций от 2 аргументов и до функций с 22-аргументами включительно.
Для функций без аргументов и с одним аргументом использовать бессмысленно.
Для функций с более чем 22-мя не поддерживается (таких трейтов вообще нет).
Например если Вы захотите сделать:
val foo = (x0:Int,x1:Int и т.д. до x22:Int) => 0
то получите ошибку компиляции:
"implementation restricts functions to 22 parameters".
Чтобы не возникало путаницы, поясню.
- Во-первых:
Это не значит, что вы не можете объявлять методы
def foo(x0:Int,x1:Int и т.д. до x22:Int) = 0
Это будет работать, но использовать в полную "силу" возможности Scala по работе с функциями уже не получится.
Можно считать, что это "обычный" метод с 23 аргументами... - Во-вторых:
Функции с varargs (переменным количество аргументов) работают нормально. Здесь никаких проблем с каррирование быть не должно. -
В-третьих:
Если у вас функции с более чем 22 аргументами это π#_!@#?!!!
Думаете такого не бывает? Когда-то я работал в организации, в которой нужно было писать и разбираться со скриптами на лиспе (было и такое в моей жизни). Так вот, некоторые умельцы декларировали функции от 15-ти и более аргументов.
Я в очередной раз взываю ко всем программистам с планеты Земля.
Пожалуйста, постарайтесь так больше не делать. Уж очень неприятно работать с таким кодом.
Блог о программировании
Scala. Pattern Matching
Продолжил работу по созданию учебных материалов по Scala.
Выкладываю черновую версию одной из глав.
Сопоставление по образцу (pattern matching). Начало.
В качестве вариантов перевода слова match с английского языка словарь Lingvo приводит следующие варианты:
В языке Scala ключевое слово match также используется для того, чтобы подбирать или находить соответствие:
Где e, e1, en - некие выражения (expression) , а p1, pn - шаблоны (pattern) по которыми мы пытаемся найти соответствия.
Такая конструкция напоминает обычный switch / case из языков программирования Java или С/C++.
Сравним примеры:
| Scala | Java | C |
|
a match {
case 0 => print("zero")
case 1 => print("one")
case _ => print("too much")
} |
switch (a) {
case 0:
System.out.print("zero");
break;
case 1:
System.out.print("one");
break;
default:
System.out.print("too much");
break;
} |
switch (a) {
case 0: printf("zero");
break;
case 1: printf("zero");
break;
default: printf("too much");
break;
} |
Tips. В Scala можно указать сразу несколько условий в case
a match { case 1 | 2 | 3 => println("один, два, или три") }Рассмотрим подробнее наш пример. В нем объект a "сравнивается" с разными шаблонами.
Для a равному 0, будет будет исполнен код print("zero").
Для а равному 1, будет выполнено print("one").
Для остальных случаев в Scala есть символ-джокер. Он обозначается символом подчёркивания _ . Таким образом case _ сработает в том случае, если другие шаблоны не подошли. Похожее поведение в Java реализуется с помощью слова default .
Tips. Символ-джокер, он же wild-card. По аналогии с карточными играми, например покером, в котором такая "дикая" карта (wild card) может стать другой картой по желанию игрока (например "пятым" тузом).
Простыми примерами таких символов может служить знак * в Unix/Windows скриптах или символ % в SQL-ном LIKE. В Scala wild-card "_" используется не только в case-ах, но и в других конструкциях.
Важной особенностью языка Scala заключается в том, что в отличие от switch/case С или Java, match умеет работать со строками. Более того match можно использовать для сопоставление объектов так называемых case классов, работу с которыми бы подробно рассмотрим в следующей главе.
Tips. Eсли мы попробуем например декомпилировать (javap -c ) указанный выше пример, мы обнаружим что Scala компилятор создаёт не плохой байт-код, аналогичный тому если бы мы писали на Java используя switch/case.
Итак, попробуем использовать полученные знания.
Представим, что у нас есть некоторый набор команд К. Например К = { F, +, - } :
F → пойти прямо
+ → повернуть направо
- → повернуть налево
Напишем программу, которая будет исполнять эти команды:
Здесь cmd - обозначает строку с последовательностью различных команд. Например "F−F++F−F", будет означать - прямо, налево, прямо, направо, направо, прямо, налево, прямо.
Значение переменных x, y, α будут задавать текущие координаты и направление движения нашей системы.
Используем ещё раз силу match и применив какую-нибудь простую L-system-у, напишем программу которая будет рекурсивно создавать нам красивую последовательность команд.
Например, пусть будет следующее правило преобразований:
F → F+F-F-FF+F+F-F
+ → +
- → -
На языке Scala это можно записать следующим образом:
Вызывая рекурсивно несколько раз данную функцию и направив полученную цепочку команд для отрисовки изображения, мы можем получить довольно занятные изображения.
Исходный код. В качестве эксперимента можно таким образом нарисовать салфетку серпинского или снежинку коха.
Продолжение следует...
Теги:
Программирование
Scala
Блог о программировании
Netbeans Scala Maven
Если вам приходилось работать в связке Netbeans 6.9.1 + Scala + Maven, то вы могли заметить, что компиляция происходит сильно медленнее, чем если бы вы НЕ использовали maven-scala-plugin.
Дело в том, что по умолчанию компиляция запускается в режиме "компилировать все классы". Такое поведение можно изменить, указав в настройках для recompileMode значение modified-only (компилировать только измененные). По-умолчанию оно all.
В некоторых случаях перевод в режим modified-only удобен, например если ваша задача не выпуск финальной версии продукта, а работа над определенным куском кода в режиме "написал, нажал Shift-F6, посмотрел что получилось...".
Внимание! Перевод recompileMode в режим modified-only может привести к нежелательным последствиям и побочным эффектам. Как говорится, не уверен - не обгоняй (а уверен - обгоняй).
Пример возможной (но далеко не оптимальной) модификации pom.xml.