Рубрики
Scala

Встречи Scala программистов в Москве

Для меня Scala не "абстрактный сферический конь в вакууме", а язык, который я использовал в нескольких реальных проектах в течение последних трех лет. Хочу сразу отметить, что мы не использовали никаких скала-фреймворков - лифт, скалаторы и прочее. Во-первых не было необходимости, во-вторых можно без особых усилий писать на scala и использовать только обычные java-фреймворки.

Кроме программирования на Scala в 2010-2011 я вел курс по выбору в МФТИ "Практикум по программированию на Java и Scala". В результате у меня наработался некоторый объём дидактического материала.

В итоге летом 2011 года мы с друзьями решили организовать в Москве независимые регулярные встречи Scala программистов.
Под "независимыми" имеется в виду - без патронажа каких либо коммерческих организаций жадных до денег или мозгов программистов.
Регулярные - старались встречаться каждую неделю, но естественно были перерывы.
Формат встреч самый простой - собираемся и решаем небольшие задачки на Scala.

Место встречи - различные кофейни и другие либеральные заведения общественного питания, в которых есть wi-fi.
Как правило встречи проводились после рабочего дня, поэтому кто-то в процессе обучения пил кофе и ел пирожные, кому-то было интересней пиво или сытный ужин.

Один человек притаскивал ноутбук (как правило это был я со своим 17'' HP).
Выбирали одну задачку на всех, она разбивалась на несколько кусочков.
Главное условие - каждый должен был написать хотя бы несколько строк кода.
Если не успеваем решить - переносим на следующую встречу.

Также кто-то на встречах рассказывал про свой опыт использования Scala у себя на работе или какие-то интересные аспекты языка.
В качестве источника информации использовали в основном стандартную документацию по API, мои презентации к физтеховским семинарам,
и книжку Мартина Одерского "Programming in Scala", которую мне подарил Коля Матюшев (книжка на английском, он ее купил когда работал в Лондоне).

Некоторые задачки которые мы решали на наших "семинарах":

  • Рисовалка Мандельброта
  • Разные фракталы на L-System-е
  • Игра жизнь
  • Решалка судоку

Места в которых проводил занятия (в хронологическом порядке):

  • КофеИн
  • Шоколадница
  • Кофе-Хаус
  • Му-Му

Думаю станет чуть потеплее и мы продолжим (а может и раньше).
Кто был на встречах: Валерия Ива Виннер, Серж, Артур, Ник, Миха, Вит.
Прошу прощения если кого-то забыл. Буду рад новым встречам!

Рубрики
0. Мироощущение и бытие Scala

Поездка в Санкт-Петербург

Прошло уже больше месяца, с тех пор как я обещал друзьям написать про свою поездку в Питер. Было очень много разных дел по работе, в итоге только сейчас смог дописать.

Рубрики
3. Инструментарий 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

netbeans_default_options="МНОГО_БУКВ   --locale en:US"

UPD: Почистить домашнюю папку ".netbeans/7.x" перед сменой локали, а то "Службы" и некоторые другие сообщения могут остаться на русском. Предварительно сделайте бэкап.

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/

Рубрики
Scala

Scala и пустота

В Scala есть несколько разных сущностей для обозначения несуществующих, пустых или неопределенных объектов.
Начнем с самого привычного для Java-программистов случая.

Null

Null – это trait. Объект null (с маленькой буквы) — это как раз и есть объект типа Null. Он находится внизу иерархии типов в Scala, в противовес AnyRef.
Благодаря этому вы всегда можете как-бы "занулить" любую ссылку, т.е. присвоить ссылки значение null:

scala> var x = "String"
x: java.lang.String = String
scala> var i = List(3)
i: List[Int] = List(3)
scala> i = null
i: List[Int] = null
scala> x = null
x: java.lang.String = null

Null работает только для ссылочных типов, для более общего случая, есть "ничто (Nothing)" .

Nothing

Nothing – это тоже trait. Nothing находится на самом дне иерархии типов, в противовес Any. Соответственно, это более общий тип, чем Null и подходит даже для AnyVal объектов (числа, буквы, правда/ложь и т.д.).

В отличие от Null, Nothing не может иметь экземпляров (на то оно и ничто).
Другими словами нет аналога null для Nothing.

Возникает вопрос, где такое самое "нижнее ничто" может использоваться?
В документации по API можно найти несколько примеров:

// пакет scala.sys
def error(message: String): Nothing = throw new RuntimeException(message)

Этот метод никогда ничего не возвращает, поэтому возвращаемый тип 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 такой фокус не выйдет).

scala> def foo():Unit = {}
foo: ()Unit
scala> val u = foo()
u: Unit = ()

Nil

Nilобъект, пустой список (extends List[Nothing]).
Поскольку Nil – это список, хоть и пустой, у него как у любого списка есть метод :: (два двоеточия), с помощью которого удобно создавать списки:

scala> var x = 1 :: 2 :: Nil
x: List[Int] = List(1, 2)

Это возможно благодаря тому, что название метода заканчивается на : (двоеточие), в таком случае метод применяется к правому операнду (работает для операторной нотации вызова метода).

Другими словами, это аналогично вызову: (Nil.::(2)).::(1)

None

None – это такой хитрый объект (extends Option[Nothing]) , который используется в случае, если мы хотим получить что-то, например, из 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] = None

None примечателен тем, что:

  • это объект (т.е. синглтон)
  • это кейс-объект
  • наследуется от 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 может работать с любыми типами (как с ссылочными так и с примитивными).

Рубрики
4. Полезняшки Java Scala

Main args, netbeans

Пара простых вещей (про аргументы командной строки + Java/Scala и чуть-чуть про NetBeans)

Самый популярный и набивший оскомину пример HelloWorld встречается, наверное, уже во всех учебниках по программированию:

// Пример из туториала: http://download.oracle.com/javase/tutorial/getStarted/application/index.html
class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!"); // Display the string.
    }
}

Здесь String[] args — аргументы командной строки.
Например:
java HelloWorldApp 1 2 означает, что args будет равно {"1", "2"}.

Рассмотрим как работать с этими аргументами.
Если передается всего один аргумент (например, "debug"), то все очень просто — можно подсмотреть пример из туториала: cmdLineArgs.

В случае, если аргументов много (как в гнусных линуксовых командах), то можно использовать какую-нибудь готовую библиотеку:

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

В том случае, если аргументы не такие сложные и не слишком простые, а что-то среднее, то тянуть для этих целей дополнительную библиотеку нет никакого смысла. Например, если нужно передать что-то вроде: "-x -size 1024 -v".
Обычно это бывает, когда требуется небольшая, почти "одноразовая" программа...

Многие настолько не любят писать разбор таких аргументов, что лепят все параметры в системные свойства (java ... -Dfoo="some string"), чтобы потом дергать их через System.getProperty().
Это конечно удобно, но не всегда нормально.

Проще написать разбор обычными стандартными средствами:

public class App {
 
    public static void main(String[] args) {
        boolean v = false, x = false;
        int size = 0;     
        for (int i=0;i<args .length;++i) {
            String arg = args[i];
            if (arg.equals("-v")) {
                v = true;
            } else if (arg.equals("-size")) {
                size = Integer.parseInt(args[++i]);//да, здесь может быть ArrayIndexOutOfBoundsException
            } else if (arg.equals("-x")) {
                x = true;
            }
        }
        System.err.println("v = " + v);
        System.err.println("x = " + x);
        System.err.println("size = " + size);
    }
}

В Scala все то же самое.
Тривиальный случай – делаем как в примере на официальном сайте: Snippet: Match Arguments.
Что-то очень сложное – подключаем сторонние библиотеки для разбора аргументов командной строки (ту же апачевскую или jopt).
В том случае, если что-то среднее, то можно написать на чистой Scala:

object App  {
  def main(args:Array[String]) = {
      var v = false; var x = false; var size = 0   
     ("" +: args :+ "") reduceLeft ( (i, j) => {
        i match {
          case "-v"     => v = true
          case "-size"  => size = j.toInt
          case "-x"     => x = true
          case _ =>
        }; j
     })
    println("v =" + v )
    println("x = " + x)
    println("size = " + size)
   }
}

Пару слов про reduceLeft. По сути этот тот же foldLeft, только начинается с первого элемента коллекции. Подробнее можно почитать в Scala API по работе с коллекциями.

Про другую известную многим фишку, о которой хотел рассказать — макросы в NetBeans-ах.
Точнее, про самый популярный макрос - debug-var. Вызывается по нажатию: Ctrl-J D.
Вообще макросы в нетбинсах есть уже много лет, по-крайне мере, когда я только начинал использовать нетбинс (3.* версии), они уже там были.
Например, для Scala можно сделать макрос, который будет вставлять в код: println("var=" + var)

Настроить можно здесь:
Tools -> Option -> Editor -> Macros

Про другие полезные макросы можно почитать здесь

Рубрики
1. Языки программирования Scala

Немного карри

Использовать карринг в Scala одно удовольствие.
Само определение каррирования(или карринга, названо в честь Хаскелла Карри):

Для функции h типа h : (A × B) → C оператор каррирования Λ выполняет преобразование
Λ(h) : A → (B → C)

Отметим, что Λ - это оператор, то есть "функция над функциями".
Например берем функцию foo(x,y), каррируем и получаем moo(x)(y) - функцию от x которая возвращает функцию от y.

Рубрики
Scala

Scala. Pattern Matching


Продолжил работу по созданию учебных материалов по Scala.
Выкладываю черновую версию одной из глав.

Сопоставление по образцу (pattern matching). Начало.

Рубрики
4. Полезняшки Scala

Netbeans Scala Maven

Если вам приходилось работать в связке Netbeans 6.9.1 + Scala + Maven, то вы могли заметить, что компиляция происходит сильно медленнее, чем если бы вы НЕ использовали maven-scala-plugin.
Дело в том, что по умолчанию компиляция запускается в режиме "компилировать все классы". Это не очень приятно, учитывая то, что Scala компилятор не очень-то быстрый.
К счастью, такое поведение можно изменить, указав в настройках для recompileMode значение modified-only (компилировать только измененные). По-умолчанию оно all.
В некоторых случаях перевод в режим modified-only удобен, например если ваша задача не выпуск финальной версии продукта, а работа над определенным куском кода в режиме "написал, нажал Shift-F6, посмотрел что получилось...".
Внимание! Перевод recompileMode в режим modified-only может привести к нежелательным последствиям и побочным эффектам. Как говорится, не уверен - не обгоняй (а уверен - обгоняй).

Пример возможной (но далеко не оптимальной) модификации pom.xml.

<plugin>
    <groupid>org.scala-tools</groupid>
    <artifactid>maven-scala-plugin</artifactid>
     <configuration> 
           <recompilemode>modified-only</recompilemode>
     </configuration>
</plugin>
Рубрики
Scala

Принцип работы FFT и Scala

Разбор алгоритма быстрого преобразования фурье (он же Fast Fourier transform, он же FFT).

Целью публикации является отобразить суть алгоритма, а не создание быстрой по скорости работы реализации.
Т.к. в этой программе я буду интенсивно использовать объекты вместо примитивных типов, а также рекурсию,
скорость работы будет заведомо уступать многим другим реализациям FFT, которые можно сейчас найти
в интернете в огромном количестве в открытом доступе.

Рубрики
2. Теория программирования Scala

Поиск. КМП-алгоритм

Недавно на досуге решил написать алгоритм КМП  (КнутаМорриса — Пратта) для Scala.

Изначально, мне нужно было решить простенькую задачку - найти последовательность байт в потоке байтов. Сделал на Java. Потом, решил сделать тоже самое на Scala. Занятно, но в стандартной библиотеке коллекций Scala используется именно КМП поиск.

Вот мой вариант.