среда, 24 июля 2013 г.

[prog.flame] Что-то уж слишком многого я не понимаю в языке Go

В попытке изучить текущий вариант языка Go (версия 1.1.1 на данный момент) прочитал почти весь документ Effective Go. Постоянно ловлю себя на впечатлении, что это какой-то хакерский язык: он был придуман хакерами для хакеров и только хакеры будут с удовольствием на нем программировать :(

Есть в Go вещи из разряда "запомнытэ это, патамушта панять это нэвозможно!". Вот, например, почему для признака публичности имени используется регистр первой буквы в имени? Т.е. MyType -- это публичное имя, которое экспортируется из пакета. А вот myType -- это приватное имя, которое вне пакета не видно.

Или еще. Почему для объявления переменных используется две синтаксических конструкции: декларация var с указанием типа переменной и декларация имени с инициализацией через оператор :=? Вот так это выглядит в коде:

var i int = 0
j := 0

Или вот почему в Go так легко запустить гороутину, но нет простого встроенного способа определить момент завершения ее работы? Нужно вручную создавать канал, передавать его в гороутину, там в конце работы что-то в канал записывать, по месту старта гороутины читать из канала. Почему бы это все не спрятать за каким-то вариантом старта гороутин? Чтобы, например, вместо

f := make(chan int)
go func(r chan int) {
   // Здесь что-то делаем...
   r <- 0
}(f)
<-f

использовать что-то вроде:

f := go func() {
   // Здесь что-то делаем...
}()
f.Wait()

Ну а апофеозом моего непонимания стала реализация неблокирующей записи значения в канал. Мой привыкший к C++ мозг был буквально разорван тем, что неблокирующая запись (как и чтение) в канал реализуется посредством оператора select (который в C/C++/Java известен как switch):

select {
case freeList <- b:
   // Buffer on free list; nothing more to do.
default:
   // Free list full, just carry on.
}

Ну вот не могло мне придти в голову, что для неблокирующей записи оператор <- нужно помещать внутрь select-а, в котором обязательно должна быть секция default. И даже после того, как я узнал об этом, мне не удается понять, какой логикой руководствовались авторы языка, придумывая такую штуку.

Я до сих пор помню свои впечатления, когда после языка Паскаль начал изучать C и как радовали C-шные конструкции i+=1 или i++ после унылых Паскалевских i:=i+1. А уж классический while(*p++) вообще широко распахивал двери в, как тогда казалось, настоящее программирование. Это потом уже, имея десятки лет опыта разработки за плечами и кучу набитых на ++, -- и дефолтных преобразованиях к bool шишек, пришло понимание, что лаконичность записи посредством хакерских штучек далеко не всегда хорошо. Поэтому сейчас видя в Go какую-то кучу приемов и приемчиков, сокращающих текст программы, но не имеющих очевидного логического обоснования, становится как-то не по себе.

Комментариев нет: