Kotlin и тараканы
От: std.denis Россия  
Дата: 07.12.15 20:08
Оценка: 15 (1)
Наткнулся тут на такую особенность Kotlin: return из функционального литерала выполняет выход из функции, в которой этот литерал объявлен. Например:
fun hasZeros(ints: List<Int>): Boolean {
  ints.forEach {
    if (it == 0)
      return true // returns from hasZeros
  }
  return false
}

Если же нужно выйти только из этого блока кода, то используется return с квалификатором:
fun foo() {
  ints.forEach lit@ {
    if (it == 0)
      return@lit // явная метка
      //return@forEach // неявная метка – имя функции
    print(it)
  }
}


Меня интересует два вопроса:
— есть ли еще какой-то язык(-и) с таким же извращением?
— что вообще может твориться в голове, чтобы так сломать распространенное поведение?

P.S. Если тут есть кто-то из команды разрабатывающей Kotlin, то у вас в трансляции в javascript есть ошибка как раз в этом гулпом поведении.
  JS-код который генерируется
hasZeroes_9mvhws$: function (arr) {
      var tmp$0, tmp$1, tmp$2;
      tmp$0 = arr, tmp$1 = tmp$0.length;
      for (var tmp$2 = 0; tmp$2 !== tmp$1; ++tmp$2) {
        var element = tmp$0[tmp$2];
        hasZeroes_9mvhws$f$break: {
          if (element === 0)
            break hasZeroes_9mvhws$f$break;
        }
      }
      return false;
    }
Re: Kotlin и тараканы
От: jazzer Россия Skype: enerjazzer
Дата: 07.12.15 20:20
Оценка: :))
Здравствуйте, std.denis, Вы писали:

SD> — есть ли еще какой-то язык(-и) с таким же извращением?


unix shell

там exit в скриптах замечательно работает ровно до тех пор, пока ты не позовешь оный скрипт через точку (ну там во время дебага посмотреть, какие он навыставлял переменные окружения, скажем), и у тебя вдруг опа — и консоль закрылась
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Kotlin и тараканы
От: AlexRK  
Дата: 08.12.15 16:54
Оценка:
Здравствуйте, std.denis, Вы писали:

SD>Меня интересует два вопроса:

SD> — есть ли еще какой-то язык(-и) с таким же извращением?

Smalltalk.

SD> — что вообще может твориться в голове, чтобы так сломать распространенное поведение?


Фиг знает.
Re: Kotlin и тараканы
От: Abyx Россия  
Дата: 08.12.15 17:15
Оценка:
Здравствуйте, std.denis, Вы писали:

SD>Наткнулся тут на такую особенность Kotlin: return из функционального литерала выполняет выход из функции, в которой этот литерал объявлен. Например:

SD>
fun hasZeros(ints: List<Int>): Boolean {
SD>  ints.forEach {
SD>    if (it == 0)
SD>      return true // returns from hasZeros
SD>  }
SD>  return false
SD>}


SD>Меня интересует два вопроса:

SD> — есть ли еще какой-то язык(-и) с таким же извращением?

может немерле? в нем же тоже вроде некоторые statements сделаны через макросы

SD> — что вообще может твориться в голове, чтобы так сломать распространенное поведение?


ну начать надо с того, что это не функциональный литерал (aka лямбда-функция).
впринципе этим бы можно было бы и закончить, но я добавлю что если
forEach ints {
    if (it == 0)
      return true // returns from hasZeros
  }
}

сильного удивления не вызывает, то что меняется от того, что мы напишем ints.forEach ?
In Zen We Trust
Re: Kotlin и тараканы
От: DarkEld3r  
Дата: 08.12.15 18:14
Оценка:
Здравствуйте, std.denis, Вы писали:

SD>Меня интересует два вопроса:

SD> — есть ли еще какой-то язык(-и) с таким же извращением?
Именно return? Потому что break с меткой встречается несколько чаще.
Re: Kotlin и тараканы
От: vsb Казахстан  
Дата: 08.12.15 18:21
Оценка: 6 (1) +2
Здравствуйте, std.denis, Вы писали:

SD>Меня интересует два вопроса:

SD> — что вообще может твориться в голове, чтобы так сломать распространенное поведение?

Мне оно кажется логичным. Почему для if () {} return возвращает из функции, а для myIf () {} return возвращает из блока? Вот это как раз нелогично. В Kotlin-е это поведение позволяет делать "свои" операторы вроде foreach и др., ведущие себя подобно встроенным в язык конструкциям.
Re: Kotlin и тараканы
От: Privalov  
Дата: 09.12.15 12:23
Оценка:
Здравствуйте, std.denis, Вы писали:

  Скрытый текст
SD>
fun hasZeros(ints: List<Int>): Boolean {
SD>  ints.forEach {
SD>    if (it == 0)
SD>      return true // returns from hasZeros
SD>  }
SD>  return false
SD>}

SD>Если же нужно выйти только из этого блока кода, то используется return с квалификатором:
SD>
fun foo() {
SD>  ints.forEach lit@ {
SD>    if (it == 0)
SD>      return@lit // явная метка
SD>      //return@forEach // неявная метка – имя функции
SD>    print(it)
SD>  }
SD>}


SD>Меня интересует два вопроса:

SD> — есть ли еще какой-то язык(-и) с таким же извращением?

RETURN n был еще в Фортране 4. Правда, в приведенном коде поведение return-а больше похоже на break label из Java. А в Фортране выполнялся возврат из подпрограммы на помеченный оператор.
Сам я подобным никогда не пользовался.
Re[2]: Kotlin и тараканы
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.12.15 17:15
Оценка: +1
Здравствуйте, vsb, Вы писали:

SD>>Меня интересует два вопроса:

SD>> — что вообще может твориться в голове, чтобы так сломать распространенное поведение?

vsb>Мне оно кажется логичным. Почему для if () {} return возвращает из функции, а для myIf () {} return возвращает из блока? Вот это как раз нелогично. В Kotlin-е это поведение позволяет делать "свои" операторы вроде foreach и др., ведущие себя подобно встроенным в язык конструкциям.


Оно может и логично, но привычного здесь мало, собтсвенно ошибка в жэес коде об том и говорит — товарищи обманули сами себя.
Re[2]: Kotlin и тараканы
От: std.denis Россия  
Дата: 10.12.15 19:54
Оценка:
A>ну начать надо с того, что это не функциональный литерал (aka лямбда-функция).
А что это как не лямбда-функция? Мне видится это лямбдой, которая передана методу расширения fun <T> Iterable<T>.forEach(action: (T) -> Unit) . Соответственно и return выглядит как return из лямбды.
Re[2]: Kotlin и тараканы
От: std.denis Россия  
Дата: 10.12.15 20:07
Оценка:
vsb>Мне оно кажется логичным. Почему для if () {} return возвращает из функции, а для myIf () {} return возвращает из блока?
vsb>Вот это как раз нелогично. В Kotlin-е это поведение позволяет делать "свои" операторы вроде foreach и др.

Да, хорошая точка зрения.
Видимо после Swift непривычно, ведь в свифте doSomething { () -> Void in ... } (запись, похожая на анонимную функцию в Kotlin) и doSomething { ... } (похожая на лямбда-выражение в Kotlin) – одно и то же, разной степени сокращенности
Re[2]: Kotlin и тараканы
От: std.denis Россия  
Дата: 10.12.15 20:11
Оценка: +2
P>RETURN n был еще в Фортране 4. Правда, в приведенном коде поведение return-а больше похоже на break label из Java. А в Фортране выполнялся возврат из подпрограммы на помеченный оператор.
P>Сам я подобным никогда не пользовался.
Да, return с квалификатором вполне понятен. Меня удивило именно поведение без квалификатора, которое разное для лямбда-функции и анонимной функции.
Re[2]: Kotlin и тараканы
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.12.15 00:42
Оценка: 3 (1)
Здравствуйте, Abyx, Вы писали:

A>может немерле? в нем же тоже вроде некоторые statements сделаны через макросы


В Немерле нет return-а. В Немерле есть макра return. Реализована она на базе оператора выхода из именованного блока.

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