LINUX.ORG.RU

Прототип замыканий (closures) в языке Java поддерживает все пункты спецификации

 , , , , , ,


0

0

Об этом сообщает в своем блоге Нил Гафтер ( http://gafter.blogspot.com/ ).

Пикантость ситуации придает тот факт, что Гафтер долгое время работал ведущим инженером (senior staff engineer) в Sun Microsystems, участвуя в реализации явы с версии 1.4 по 5.0.

После этого Гафтер перешел в компанию Микрософт, где и работает в настоящее время над языками dotnet. Тем не менее, в свободное время Гафтер участвует в развитии языка Java, как он сам пишет для того, чтобы "сбалансировать свою жизнь" (To balance his life).

>>> Спецификация замыканий в яве

Интересно, лямбду реализуют?

cab ★★★★
()
Ответ на: комментарий от anonymous

> А кто-нибудь может объяснить на пальцах, что есть замыкания (closures) и, главное, какое преимущество от их использования?

1. Тебе не нужен тупняк с определением новой функции -- ты ее определяешь на месте использования

2. Ты можешь изготовлять собственные структуры управления -- аналоги if, for, switch, ... (правда только аналоги if и for будут выглядеть прилично)

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

п. 3 для полноты приведу, но это уже не на пальцах:

3. Компилятор позаботится о связанной внутри замыкания переменной.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от Macil

>>Никаких функциональных преимуществ нет

>Ну, в императивных языках преимущества скорее нотационные.

А вот отсюда поподробнее. Ява (хотя и говно, конечно) императивный язык или нет? Что такого можно сделать в чем-то неимперативном, чего нельзя или неудобно в яве?

(я яву не люблю, но объективность требует...)

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

Re^2: Прототип замыканий (closures) в языке Java поддерживает все пункты спецификации

> 2. Ты можешь изготовлять собственные структуры управления -- аналоги if, for, switch, ... (правда только аналоги if и for будут выглядеть прилично)

Кстати, а получится ли for? Сейчас-то жабка ругается, если переменные "верхнего" контекста в замыкании объявлены не как final.

gaa ★★
()

> Вот здесь http://www.gafter.com/~neal/resume.html английским по белому написано, что ушел он из Гугла не "очень давно", а в сентябре, а узнали об этом только на JavaPosse так что новость от 29.09.2008 была правильной и удалена Shaman007 по причине '4.2 Вызывающе неверная информация' незаконно.


Не все так просто.

В той новости ( http://www.linux.org.ru/view-message.jsp?msgid=3127459 ) написано "один из блистательной плеяды разработчиков Java покинул команду", что очевидно понимают как "покинул Сан", так что позиция Шамана имеет смысл:

1. Если Нил команду покинул, то произошло это в July 2004 году, когда он уволился из Сан, а вовсе не в сентябре, когда уволился из Гугля

2. Не факт что он покинул команду. В том резюме написано о работе над явой: July 2006 - present (part time), так что он не покинул команду. Резюме в этом аспекте up-to-date, так как первой строкой идет:

Microsoft
September 2008 - present
Partner Architect, Visual Studio Managed Languages


З.Ы. Пиши новость правильно сразу, и будет тебе щастье.

З.Ы.Ы. Не отрицаю того, что де-факто покидание случится только сейчас, но писать об этом надо чуток по-другому.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

чуток по-другому: в виде прогноза и будущего времени.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

>А вот отсюда поподробнее

В сабже замыкание - неявное объявление интерфейса. В принципе, это можно сделать руками хоть прямо щас. Опять же, как я уже говорил, существет шаблон Functor, который позволяет моделировать все что угодно, хоть "лямбды", хоть "замыкания", хоть ленивые вычисления.

Так что преимущества скорее нотационные.

>Что такого можно сделать в чем-то...

Вообще, все мы пишем под одну конкретную машину - машину Тьюринга. Так что вопрос совершенно неуместен.

Macil ★★★★★
()

> Кстати, а получится ли for? Сейчас-то жабка ругается, если переменные "верхнего" контекста в замыкании объявлены не как final.

Получится, так как можно будет не финальные (и даже появился атибут @Shared)

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от Macil

>>Что такого можно сделать в чем-то...

>Вообще, все мы пишем под одну конкретную машину - машину Тьюринга. Так что вопрос совершенно неуместен.

повторю: ...чего нельзя или неудобно в яве,

так что как минимум слово "неудобно" и вместе с ним уместность имеется.

Вот например в С, хотя и можно сделать собственные конструкции типа foreach через макросы препроцессора, но положить их в переменную или передать в виде параметра в функцию вообще нельзя (однако макросы точно не теряют эффективность, и насколько будут эффективны конструкции в яве -- это вопрос)

>Ну, в императивных языках преимущества скорее нотационные.

Хорошо, а что все-таки имелось в виду?

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

>Хорошо, а что все-таки имелось в виду?

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

Macil ★★★★★
()
Ответ на: комментарий от Macil

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

Мне писать и читать удобне си-подобный или питоновский синтаксис.

Что касается неконсистентности си-подобного синтаксиса -- то это очень сильно проявляется тогда, когда думаешь его расширять.

Поэтому возникает желание придумать более консистентный синтаксис.

(И еще замечу, что консистентность синтаксиса с императивность языка связаны отнюдь не жестко).

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от Macil

>>Хорошо, а что все-таки имелось в виду?

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

Мог бы дать ссылочку на какой-нить свой развернутый пост. Ладно, отвечу исходя из просмотренных мной прошлых постов:

Если императивность понимается фактически как слабость метапрограммирования -- то да, так оно и есть. И вообще объявить какую-то непредусмотренную языком иерархию (не класс, -- для последующего использования) -- очень трудно что в плюсах, что в яве. В С/С++ это делаеться УГ на макросах.

Новый синтаксис должен давать возможность сделать это влегкую.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

( В яве это делается на неполноценных аннотациях или супермногословных run-time инициализациях с последующим метапрограммированием "для бедных" -- через класслоадер и рефлексию ).

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>Тормозной, в 50 раз медленнее жабского, рантайм.

http://bistro.sourceforge.net/

>Язык не пригоден для промышленного применения


Это новость.

>Да и стоит килобаксы


4.2

r ★★★★★
()

>Сейчас-то жабка ругается, если переменные "верхнего" контекста в замыкании объявлены не как final.

В BGGA компиляторе не ругается на замыканиях. Можно обявить как файнал или проаннотировать как @Shared (не понял нафик это надо). Если не аннотировать - варнинг.

r ★★★★★
()

какой-то аццкий гибрид паскалевских вложенных функций и сишных дефайнов и полная невнятность со временем жизни связанных переменных, вероятно без сборщика мусора такое вообще нежизнеспосбно:

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

tups
()
Ответ на: комментарий от Macil

>Вообще, все мы пишем под одну конкретную машину - машину Тьюринга. Так что вопрос совершенно неуместен.

А есть еще какие-то машины, кроме Тьюринга? А то 23 года слышу Тьюринг, Тьюринг, а как эта машина выглядит, не представляю

anonymous
()
Ответ на: комментарий от www_linux_org_ru

>И вообще объявить какую-то непредусмотренную языком иерархию (не класс, -- для последующего использования) -- очень трудно что в плюсах, что в яве.

Пример можно, какие управляющие конструкции, кроме for, while, if, еще бывают нужны? Какие еще непредусмотренные языком иерархии бывают? Чтобы возникала необходимость их объявлять самому а не пользоваться готовыми

anonymous
()
Ответ на: комментарий от anonymous

#MPEG-2 Sequence Header
header name "Sequence" code 0,0,1,0xB3 length 8;

map aspectratio values 1 => "1:1", 2 => "4:3", 3 => "16:9", 4 => "2.21:1";
map framerate values 1 => "23.976", 2 => "24", 3 => "25", 4 => "29.97", 5 => "30", 6 => "50", 7 => "59.94", 8 => "60"

attribute horizontal-size int = 0,1:7..4;
attribute vertical-size int = 1:3..0,2;
attribute aspect-ratio aspectratio = 3:7..4;
attribute frame-rate framerate = 3:3..0;

r ★★★★★
()
Ответ на: комментарий от tailgunner

Управляющие конструкции - это словосочетание анонимуса - сайтоодноименный коллега говорил об необпределенных языком иерархиях, что я понял как о концепциях которые в языке не существуют.

А в квоченом куске управляющих конструкций нет - все в декларативном виде.

r ★★★★★
()
Ответ на: комментарий от r

С другой стороны вот те мапы эквивалентны switch, а заголовок с кодом это грубо говоря do read while(4 считанных байта не равны коду).

r ★★★★★
()
Ответ на: комментарий от anonymous

Re^2: Прототип замыканий (closures) в языке Java поддерживает все пункты спецификации

> Пример можно, какие управляющие конструкции, кроме for, while, if, еще бывают нужны?

synchronized(mutex), try-catch-finally, lambda, closure, iterate_over_sql_query_cursor, iterate_over_tree_{bfs,dfs}, iterate_over_any_iterator... Ещё надо?

gaa ★★
()

> Ещё надо?

А хорошо бы составить полный список.

Кстати, все эти iterate_over в нормальном языке (не яве) делаются через перегрузку оператора ++ у итератора.

Вот один пример, который в С/С++ можно сделать на макросах (правда не очень красиво):

with(mylock, 50) {
// делаем что-то в случае захвата лока в течение 50 мс
}else{
// делаем другое, если лок не удалось захватить за 50 мс
}

Что эквивалентно:

if( locked(mylock, 50) ) {
try{
// делаем что-то в случае захвата лока в течение 50 мс
}finally{ unlock(mylock); }
}else{
// делаем другое, если лок не удалось захватить за 50 мс
}

Преимущество первой формы в том, что:
1. писанины меньше
2. unlock(mylock); невозможно забыть

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

>Кстати, все эти iterate_over в нормальном языке (не яве) делаются через перегрузку оператора ++ у итератора.

Это как раз ненормальный язык. В любом нормальном языке есть соответствующий тип.

>Вот один пример, который в С/С++ можно сделать на макросах (правда не очень красиво):


А можно код такой макры?

r ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Есть конечно объектный вариант "сделать объект из лок-а", но все равно потребует лишние скобки:

function(...){

{ // лишняя скобка

Lock l(mylock, 50);
if(l.locked) {...} else {...}

} // лишняя скобка

// здесь код, который может долго выполняться

}


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

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от r

> Это как раз ненормальный язык. В любом нормальном языке есть соответствующий тип.

Отсюда поподробней. Чему соответствующий тип? Какого типа итератора тебе нехватило?

> А можно код такой макры?


Можно, но попозже.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

* чтобы какая-то функция (аналог плюсового деструктора) гарантированно выполнилась по закрывающей скобке, а не х.з. когда сборщик мусора проснется?

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

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

finally или написать там ее вызов. На сборщик мусора вообще ничего завязывать нельзя.

r ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Re^4: Прототип замыканий (closures) в языке Java поддерживает все пункты спецификации

> А хорошо бы составить полный список.

Подозреваю, что их количество не является конечным.

> Кстати, все эти iterate_over в нормальном языке (не яве) делаются через перегрузку оператора ++ у итератора.


Итератор плох тем, что придётся иметь в виду возможность его сохранения. А возможность произвольного доступа не всегда есть и не всегда легко реализовать.

gaa ★★
()
Ответ на: комментарий от www_linux_org_ru

>Чему соответствующий тип?

Итерабельности.

>Какого типа итератора тебе нехватило?


Дело в обобщенности подхода. Итерабельность - это обдно из вожзможных свойств некоей структуры. Если обратиться к этим перечисленным управляющим структурам то по сути чем

foreach(e : l) { ... }

отличается например от

sort ( l ) { ...предикат ... }

или от

collect( l ) { ...трансформирующая функция... }

?

Их тоже можно ввести в ранг управляющих структур.

Точно так же как в смолтолке например ifы - это методы булеана

a > b ifTrue: [ block ]
ifFalse: [ block ]

то есть по идее в хорошем языке не должно быть if или for вообще - должен быть унифицированный механизм обявления всего чего мне надо. А не "для того чтобы чего-то там итерировалось надо сделать перекрытие некего оператора (что само по себе уже колдобина в языке).

r ★★★★★
()
Ответ на: комментарий от r

это я собственно про языки общего назначения

r ★★★★★
()

> Подозреваю, что их количество не является конечным.

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


> Итератор плох тем, что придётся иметь в виду возможность его сохранения.


Сделай копирующий конструктор и оператор & приватными.

> А возможность произвольного доступа не всегда есть и не всегда легко реализовать.


Это совсем не ясно. Итератор не предполагет произвольный доступ. Он даже не всегда предполагает --.

www_linux_org_ru ★★★★★
() автор топика

> Подозреваю, что их количество не является конечным.

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

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

Re^6: Прототип замыканий (closures) в языке Java поддерживает все пункты спецификации

>> Подозреваю, что их количество не является конечным.

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


А почему бы и нет? Почему бы не делать конструкции checkResult {}, doSomethingAndLogStderrToFile просто потому, что так удобно?

>> Итератор плох тем, что придётся иметь в виду возможность его сохранения.


> Сделай копирующий конструктор и оператор & приватными.


Логично.

>> А возможность произвольного доступа не всегда есть и не всегда легко реализовать.


> Это совсем не ясно. Итератор не предполагет произвольный доступ. Он даже не всегда предполагает --.


Да, действительно что-то не то сказал...

Но всё же итераторы хуже "конструкций" тем, как и то и другое внутри реализовывается: в итераторе переход к следующему элементу делается в ++, а там надо будет восстановить контекст, сделать шаг, сохранить контекст. Уже даже на обходах графов безытераторный код оказаывается много нагляднее.

gaa ★★
()
Ответ на: комментарий от www_linux_org_ru

Re^6: Прототип замыканий (closures) в языке Java поддерживает все пункты спецификации

>> Подозреваю, что их количество не является конечным.

> Но если сказать так: "этих конструкций достаточно много, чтобы их изготовлять по единой технологии, доступной не только разработчикам компилятора" -- то я соглашусь.


Согласен на такую формулировку.

gaa ★★
()
Ответ на: комментарий от r

> А можно код такой макры?

Юзаем гнутые расширения, которые поддерживает интел -- без них С и плюсы не юзабельны ИМХО.

#define WITH(var, time) if( locked(var, (time)) ) { typeof(var)& _var=var; try

#define ELSE finally{ unlock(_var); }}else

// тупой пример использования:

int i=0;

WITH(lock,50){

i=1;

}ELSE{

i=2;

}

www_linux_org_ru ★★★★★
() автор топика

> в итераторе переход к следующему элементу делается в ++, а там надо будет восстановить контекст, сделать шаг, сохранить контекст.

++ обычно бывает inline.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от r

>>Чему соответствующий тип?

>Итерабельности.


Этот тип называется MyContainer<Elem>::forward_iterator

> Дело в обобщенности подхода. Итерабельность - это обдно из вожзможных свойств некоей структуры. Если обратиться к этим перечисленным управляющим структурам то по сути чем foreach(e : l) { ... } отличается например от sort ( l ) { ...предикат ... } или от collect( l ) { ...трансформирующая функция... } ?


Хороший вопрос.

foreach(e : l) { e=0; }
sort ( e1, e2: l ) { e1.toUpper().lexicograficallyLessThan(e2.toUpper); }
int result=0; reduce( e: l ) { result+=e; }

Однако: как только тебе придется перебирать параллельно пару структур, сразу foreach будет недостаточно.

И либо придется юзать итераторы:

while( it1!=null && it2!=null ) {
if( it1.get() > it2.get() ) ...
it1=it1.next(); it2=it2.next();
}

либо ждать, пока санки сделают foreach2 :-)

И кстати: it2=it2.next(); кошерно, а ++it2; уже некошерно?

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от r

> a > b ifTrue: [ block ] ifFalse: [ block ] то есть по идее в хорошем языке не должно быть if или for вообще - должен быть унифицированный механизм обявления всего чего мне надо.

Ммм...

Оно все так выглядит красивенько, консистентно и академично (что есть плюс), но у меня смутные сомнения есть по этому поводу -- не потянет ли эффективная реализация такой конструкции кучу сложностей.

Если не потянет, то так надо и делать.

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

Пример про reduce лучше вот так:

int sum = reduce( result, e: l ) { result+=e; }

www_linux_org_ru ★★★★★
() автор топика
Ответ на: комментарий от www_linux_org_ru

> либо ждать, пока санки сделают foreach2 :-)

В скале есть:) При чем достаточно хитрый моэно даже так:

for (val x <- l; val y <- x.inner; val z <- y.inner)....

>Однако: как только тебе придется перебирать параллельно пару структур, сразу foreach будет недостаточно.


Вот именно. А во всяких прочих языках будет что-то типа:

list.iterateWith(list2) { (x, y) => x + y}

>И кстати: it2=it2.next(); кошерно, а ++it2; уже некошерно?


Ни то ни то некрошерно - оно должно быть запрятано в код самого foreach.

r ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> Если не потянет, то так надо и делать.

Угу - только пока нету языка где все это есть. Вот в скале хитрые конвеншены "инфиксным вызовам" прикольно - иожно изобразиь что угодно в виде

x <=-/\-=> y что по факту будет x.<=-/\-=>(y) - но там отсутствуют приоритеты - и компилятор типа "очень догадливый" если например заделать новые знаки для плюса и минуса то

x +| y *| z +| q - посчитается правильно без всяких телодвижений, а если умножение обозвать как нить по другому (без * вначале) - то уже неправильно - и процесс этот вроде бы неконтролируем, что очень жаль.


В хаскеле есть выставление приоритетов и ассоциативности - там круче.



r ★★★★★
()
Ответ на: комментарий от r

> а - а я уж испугался что изобрели совсем чето новое что позволяет "огибать" код :)

Возможно, что я смогу "согнуть" любой код сишными макросами под любую форму... но не даю гарантию :-)

www_linux_org_ru ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.