LINUX.ORG.RU

Clojure 1.1

 , ,


0

0

Вышла новая версия языка программирования Clojure. Clojure является динамически типизируемым и компилируемым языком общего назначения для JVM и CLR. Изменений много. Среди них:

  • поддержка примитивных массивов (primitive array generators)
  • chunked-последовательности
  • futures, предназначенные для асинхронных вычислений
  • promises для обмена данными между тредами
  • pre- и post условия для функций
  • новое пространство имён

Полный список изменений тут

>>> Подробности

★★★★

Проверено: maxcom ()
Последнее исправление: maxcom (всего исправлений: 1)

Ответ на: комментарий от yyk

>Генерим (при компиляции) «анонимный» класс, унаследовав от «служебного», с конкретной реализацией.

При компиляции чего?

У тебя есть декларация:

class A {
def xxxx[A <: {def substring(Int):String }] (s:A) = s.substring(4);
}

все больше ничего нет. Во что ты его откомпилишь?


Надо ещё неявное преобразование строки в класс а-ля


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

new A().xxxx(new B()).

И A и B чужие классы компилившиеся в разное время раздельно и ничего не знают друг о друге. Только компилятор может взять сигнатуру метода xxxx и проверить структурное соответствие (наличие метода substring с нужной сигнатурой). Но сделать он ничего не может - это просто классы в classpath.

Точно так же ничего не может сделать байткод манипуляция. Ведь это даже не информация о структуре классов это просто байткод типа:

invokespecial A.<init>()
invokespecial B.<init>()
aload...
invokevirtual A.xxxx(???)

что написать вместо ??? - синтетический интерфейс? Но B его не реализует - получишь CCE. И инструментить этого нельзя - потому что неизвестно во время загрузки B что он должен его реализовывать - это просто кусок кода, таких кусков миллион как и возможных синтетических интерфейсов. Мало того что нельзя найти все такие интерфейсы (нет механизма в класслоадерах для получения списка доступных классов), так для того чтобы выяснить какие нужно заинструментить в B нужно проанализировать _весь_ байткод, что невозможно как физически так и потому что обламывается на первом же условном переходе - а вдруг бы эта ветка никогда не исполнилась для экземпляра B?


Весь этот код будет-же компилироваться - не?


Да - только в трех независимых местах. Раздельная компиляция.



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

К стати для того и изобрели invokedynamic (забивающий на наследование и реализующий на уровне байткода дактайпинг), и interface injection (вставка интерфейса on-demand в уже загруженый класс) - все это будет в семерке. Потому что иначе выхода нет - рефлекшен и вперед.

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

У тебя есть декларация:


class A {

def xxxx[A <: {def substring(Int):String }] (s:A) = s.substring(4);

}


все больше ничего нет. Во что ты его откомпилишь?


interface service.WithMethodStringI {
method String substring(int i);
}

class A {
method String xxxx(service.WithMethodStringI s) {
return s.substring(4);
}
}

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


Да, но при компиляции

x.xxxx(«aaaa»)


класс объекта x и его метод xxxx (его сигнатура) «доступны и известны».

Или ты имел в виду, что методу xxxx можно подсунуть всё, что «имеет» метод substring? Так даже в семёрке сие возможно только с invokedynamic. А о прочих «ближайших планах» изменений в JVM мне не известно.

К стати для того и изобрели invokedynamic (забивающий на наследование и реализующий на уровне байткода дактайпинг)


только, блин, это тормоз ещё похлеще invokevinterface, и, соответственно, его использовать надо ещё более осторожно.

interface injection (вставка интерфейса on-demand в уже загруженый класс) - все это будет в семерке.


Где? Всё что я нашёл - http://jcp.org/en/jsr/detail?id=299 - «JSR 299: Contexts and Dependency Injection for the JavaTM EE platform» - к обсуждаемому никак не относится.

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

>Так даже в семёрке сие возможно только с invokedynamic. А о прочих «ближайших планах» изменений в JVM мне не известно.

Имел в виду - можно организовать вызов. «Забить» сие в сигнатуру метода и в 7-ке не представляется возможным.

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


interface service.WithMethodStringI {
method String substring(int i);
}

class A {
method String xxxx(service.WithMethodStringI s) {
return s.substring(4);
}
}

Бессмысленно, потому что B не реализует service.WithMethodStringI, и потому будет ошибка типов на стадии компиляции.

Или ты имел в виду, что методу xxxx можно подсунуть всё, что «имеет» метод substring?


Точно. Структурные типы.


Так даже в семёрке сие возможно только с invokedynamic.


Об том и речь. А сейчас это работает через рефлекшен. И таких ходов в языках под JVM куча.

Где?


http://openjdk.java.net/projects/mlvm/subprojects.html

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

А, давинчи... Надеюсь она не сведёт скорость работы программ ниже плинтуса. Ибо толку тогда от неё. Хотя можно клепать различные «glue» - для «обвязки» java-библиотек.

И таки да - это не jvm, и в последней ничего такого пока не планируется.

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