Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет kouzdra ([info]kouzdra)
@ 2009-04-06 14:42:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:Философическая муть

"Превед!"
Крылов тут вспоминает Воннегута

class preved {
   static public void main (final String [] args) {
     System.out.println ("Hello!");
   }
}


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

Такие дела :)


(Читать комментарии) - (Добавить комментарий)


[info]alamar
2009-04-08 02:25 (ссылка)
В .net есть возможность заводить типы, которые не будут обязательно размещаться в куче - в C# это выглядит как struct (хотя реально оно несколько шире).
Отлично. Приделали жабе на плечо крюк, как у пирата.
Зачем - вопрос другой.

Это важная фича - потому что "встроенные типы" Java - жуткая кривь. В C# int и прочие ничем не выделяются в смысле статуса.
Я не понимаю, чем struct помогает против встроенных типов.
Можно примеры кода?

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

Не понимаю, что такое передача значений по ссылке.
Все пользуются этой терминологией, как бог на душу пошлёт.
В жабе все объекты всегда передаются по ссылке. На объект в куче :)
Если вы имеете в виду передачу ссылки с возможностью обновления ее значения у вызывающего, то ИМХО - это говно с непонятной семантикой. Но в любом случае - на вторую руку Венере привесили бензопилу.

unsafe как раз совершенно не интересное - неизбежное следствие задачи, именно поддержать мультиязыкововсть на уровне хотя бы С/C++.
Не согласен. unsafe очень полезен для создания биндингов к нативным библиотекам. Не надо таскать с собой враппер-заглушку!

Это все бестиповые интерпретируемые языки - они понятно, что ложатся без проблем, да и эффективность потерять трудно. А вот уже Pascal даже или C# (даже без Unsafe) в JVM фиг нормально оттранслируешь.
Пас кал не нужен.
Что в C# такого, что сложно оттранслировать в JVM?
struct? struct не нужен.
Делегаты? Делегаты да :(
Что ещё?

В пользу наработок сделаных в FP
Я пока не знаю FP-языков, на которых было бы понятно, как писать, и которые не были бы просраны.
Лиспы все - EPIC FAIL, на хаскелле никто не понимает, как писать.
Окамл обладает достаточным количеством императивных фич, чтобы на нём писать на ассемблере ПДП-7 :)

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 02:58 (ссылка)
Зачем - вопрос другой

Затем, во первых, что то, что для того, чтобы представить например комплексное число (ну упорядоченную пару любую на самом деле), его надо заставлять прыгать по куче - это довольно порядочная задница - потому что выражение типа a.add (one) будет заводить новый объект в куче и прописывать все его поля - тормоза очень изрядные. А массив с таким подарком будет занимать места в два раза больше, чем из структур.

Кстати - тестовая программа на С++ из того бенчмарка ускоряется в полтора раза после подключения к ней бемовского GC - что и ожидалось - она очень выгодна для Java (в которой именно из-за того, что куча там юзается много и не по делу в оптимизацию этого процесса вложили очень много сил) и невыгодна для С++.

Я не понимаю, чем struct помогает против встроенных типов.
Можно примеры кода?


Тем что int - это и есть структура, если мне память не изменяет - System.Int32 на самом деле.

Соотвественно - с ним работает рефлексия и проч. Ну и с того момента, как он появился - полиморфизм - в C# int может быть типовым параметром, а Java - нет.

Если вы имеете в виду передачу ссылки с возможностью обновления ее значения у вызывающего, то ИМХО - это говно с непонятной семантикой

Что там непонятного? А главное - вещь стандартная совершенно и нужная. Везде, кроме Java. В IDEA вон даже рефакторинг есть для конверсии переменной в массив из одного элемента - ввиду того, что по человечески нельзя сделать.

struct? struct не нужен.

Ну да - вот есть программа на C# - на вопрос, а почему она не компилируется - ответ "а потому что там struct, а он не нужен" - транслироваться должна любая программа :))))

Делегаты? Делегаты да :(

Делегаты как раз никаких проблем не представляются - это просто причесанный синтаксически Runnable & co - так и транслируется. Но я пожалуй завершусь - ввиду дремучести собеседника в уже элементарных совсем вещах.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 03:14 (ссылка)
Затем, во первых, что то, что для того, чтобы представить например комплексное число (ну упорядоченную пару любую на самом деле), его надо заставлять прыгать по куче - это довольно порядочная задница - потому что выражение типа a.add (one) будет заводить новый объект в куче и прописывать все его поля - тормоза очень изрядные.
Ээээ.
Ты в курсе, что объекты бывают mutable?

А массив с таким подарком будет занимать места в два раза больше, чем из структур.
Скинуться тебе на планочку памяти?
Я вовсе не уверен, что будет в CLR с со списком из твоих структов.
Где они будут храниться? Кем заполняться? Это очень нетривиальная задача, я не уверен, что они ее решили, как тебе грезится.

Соотвественно - с ним работает рефлексия и проч.
Так, давай начистоту.
ЧТо значит - с ним работает рефлексия?

Ну и с того момента, как он появился - полиморфизм - в C# int может быть типовым параметром, а Java - нет.
Да, а зачем?
Integer может быть, и они взаимозаменяемы.

А главное - вещь стандартная совершенно и нужная. В IDEA вон даже рефакторинг есть для конверсии переменной в массив из одного элемента - ввиду того, что по человечески нельзя сделать.
Зачем? За чем?
Если ответ - "чтобы возвращать два значения вместо одного", то это разжижение мозгов.
Для возвращения двух значений пидарасам не дебильные префиксы к параметрам нужны - in, out, не кантовать, при пожаре выносить; а им нужен банальный destructuring bind.
String a, b;

a, b = returnTwoStrings();

Или хотя бы class Pair<U, V>
Пока пидарасы этого не поймут, я считаю, что это вещь ненужная.

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

Семантику destructuring bind я понимаю.
Семантику Pair я понимаю.
Семантику [in, out] я НЕ ПОНИМАЮ.
Я не понимаю, что там у него внутри происходит и зачем.
Я не понимаю, какая у этого метода после этого сигнатура и что в него передаётся.
Я очень не люблю магию.

Плюс - читать такой код неприятно. Не понимаешь, где присвоения!

Ну да - вот есть программа на C# - на вопрос, а почему она не компилируется - ответ "а потому что там struct, а он не нужен" - транслироваться должна любая программа :))))
for i in **/*.cs; sed --in-place s/struct/class/ $i; done
Вопросы? Предложения?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 22:13 (ссылка)
Ты в курсе, что объекты бывают mutable?

Бывают - а еще бывает ественное желание не писать вычисления в assembler-style. Особенно с учетом того, что это лет 40 уже "не бином ньютона".

а им нужен банальный destructuring bind. String a, b;

Это в FP, FYI, является весьма частным случаем т.н. pattern matching - тоже уже четверть века исполнилось. К вопросу о том, что там ценного.


Так, давай начистоту.
ЧТо значит - с ним работает рефлексия?


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

Семантику [in, out] я НЕ ПОНИМАЮ.

Ссылку на вики я уже дал. Это 50 лет как устоялось.

Я не понимаю, какая у этого метода после этого сигнатура и что в него передаётся.
Я очень не люблю магию


Это не магия - это самые элементарные сведения в програзме - мне это в 9ом классе в школе рассказывали. В пару-тройку первых месяцев обучения программированию в 1980 году.

for i in **/*.cs; sed --in-place s/struct/class/ $i; done

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

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 22:44 (ссылка)
"Что такое рефлексия - объяснять не буду - RTFM."
Я знаю, что такое рефлексия.
Я не понимаю, что значит "с ним работает рефлексия".
Рефлексия работает со всем.
Есть такая штука, называется int.class, не поверишь.
Методов у intа нету, понятно.
Однако я до сих пор не знаю, что такого полезного в плане рефлексии в C# можно сделать со структурами, и чего из этого нельзя сделать с примитивными типами. Ты это высказал, тебе это и объяснять.

Напомню, ты заявил:
Соотвественно - с ним работает рефлексия и проч
Так вот.
Я жду объяснений на тему, какая именно рефлексия работает с Int32 в CLR и при этом не работает с int в JVM? Я, заметь, не утверждаю, что разницы нет; просто я хочу, чтобы ты написал, в чем заключается разница и почему это важно.

"Задачу написать программу, которая после этой замены перестанет работать я оставлю в качестве упражнения."
Так ее и починить можно обратно, пойми ты.
structы достаточно тривиально реализуются в компиляторе, насколько я понимаю.
Если есть какие-то подводные камни, предлагаю их назвать, а не юлить.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 22:53 (ссылка)
Однако я до сих пор не знаю, что такого полезного в плане рефлексии в C# можно сделать со структурами, и чего из этого нельзя сделать с примитивными типами

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

Так ее и починить можно обратно, пойми ты

Предлагаю более простую задачу - берем, ну к примеру, GTK+, в ней заменяем все struct на class (обращу внимание - в С++ семантика от этого не поменяется - просто компилироваться кое-что перестанет - в С# большую часть ошибок придется искать с тестами, отладчиком и баг-репортами от юзеров "почему ваше говно все время валится") - и "чиним ее обратно" - а потом задаем вопрос - кому такой секс нужен. А самое главное - кому нужен компилятор, который не заведомо способен скомпилировать программу, соотвествующую стандарту

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 23:03 (ссылка)
"Предлагаю немножко подумать, почему в Java встроенные типы (а также массивы из них) не могут быть параметрами generic-ов."
Их автобоксы могут, а они взаимозаменяемы.
В чём проблема?

Почему ты считаешь, что надо добавить в язык дополнительные сущности вместо того, чтобы свести все типы к boxed-вариантам?

"А самое главное - кому нужен компилятор, который не заведомо способен скомпилировать программу, соотвествующую стандарту"
Я тебе повторю, вполне можно написать компилятор, который отлично оттранслирует программу на C# (со structами) в JVM.
Если ты не согласен, приведи аргументы, в чём возникнут сложности?

Ну и да, GTK+ на C написан.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 23:19 (ссылка)
Их автобоксы могут, а они взаимозаменяемы

Предлагаю несложное упражнение - в чем разница в семантике функций:

    public static boolean compare_int (int a, int b) { return a == b; }
    public static boolean compare_Int (Integer a, Integer b) { return a == b; }


(Она есть и весьма существенная)


(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 23:55 (ссылка)
Integerы могут быть null.
Integerы некорректно сравнивать оператором ==.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]b-al-u.livejournal.com
2009-04-09 10:11 (ссылка)
Насколько я помню жабу, то у Integer-ов разные ссылки, которые являются значением, которое сравнивается при помощи "==". При этом значение по ссылке может быть любым.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 12:58 (ссылка)
Смотрите, вы просто говорите то же, что и я, но длиннее. "у Integer-ов разные ссылки, которые являются значением, которое сравнивается при помощи "=="." А я сказал "== сравнивает ссылки" Вам кажется, что добавляя слова (ссылка, значение, значение, ссылка) вы уточняете, но на самом деле вы запутываете всё дальше и себя, и того, кто вас читает. У ссылки есть "значение". Но у ссылки нет "ссылки" То есть, "значение ссылки" - это тавтология. Есть либо ссылка (которая сравнивается по ==), либо просто значение (которое сравнивается по .equals()). Сравнивает ссылки. Да, в случае с объектами этого делать не стОит.

(Ответить) (Уровень выше)


[info]kouzdra
2009-04-09 14:20 (ссылка)
На самом деле - "могут быть разные" - от значения зависит: небольшие (кажется до 128) Integer'ы закешированы и ссылки на них всегда одни и те же, а вот больше - уже разные. Одна из самых милых вещей в Жабе: на тестовых примерах они будут вести себя скорее всего одинаково, а потом можно с увлечением ловить баги :)

(Ответить) (Уровень выше)


[info]alamar
2009-04-08 21:33 (ссылка)
Ну и да
"ввиду дремучести собеседника"

Создаётся ощущение, что ты хам.

Более того, автоматически создается ощущение, что тезисы у тебя кончились.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 22:01 (ссылка)
Просто очень трудно вести содержательное общение с собеседником, который не владеет самыми элементарными понятиями в обсуждаемой области - то не знает что такое "передача по ссылке", то не понимает, как реализуются замыкания (частным случаями которых являются и делегаты и анонимные классы Java), то не понимает, что реализация языка программирования должна реализоваывать его полностью - вне зависимости от мнения о полезности его фич. etc etс.

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

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 22:26 (ссылка)
Это очень интересная самозащита - каждый раз, когда собеседник с тобой не согласен, считать, что он Не Понимает. Причем не тебя, а Чего-То Важного.

Так вот.
что такое "передача по ссылке"
sokrat_ruen
ссылка
reference

In call-by-reference evaluation, a function receives an implicit reference to the argument, rather than a copy of its value. This typically means that the function can modify the argument, what will be seen by its caller.
Так вот, в языке Java передача всех объектов при вызове метода происходит исключительно по ссылке.
ср. с "В Java нет передачи значений по ссылке"
Если ты по-своему интерпретируешь термины или вносишь неявные ограничения, то не обижайся, что тебя Не Понимают.
Иначе признай, что тут ты сказал лажу полную
Вот прям тут.
Как связуется фрагмент на английском с цитатой из тебя?

Хочу уточнить: если же ты имел в виду, что примитивные типы передаются по значению, то не спеши тереть ручки и ухмыляться, ты читать не умеешь: я явно указал "единственный способ передавать объекты".

Я жду некоторой сатисфакции.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 22:30 (ссылка)
Я вынужден констатировать, что имеет место случай "смотрю в книгу, а вижу фигу". Еще раз повторю - в Java нет передачи значений по ссылке и этот текст вполне однозначно это утверждает.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 22:51 (ссылка)
"Еще раз повторю - в Java нет передачи значений по ссылке"
Хоть десять раз повтори.

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

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 22:58 (ссылка)
В Жабе все объекты представляются ссылочными значениями и эти значения передаются по значению, а не по ссылке.

Ну проще говоря - если брать Симулу, с которой Жаба в значительной степени содрана, то там все объекты тоже ссылки - даже так и описываются:

ref (C) c;

А вот передаваться они могут по разному:

procedure swap (a, b);
ref (C) a, b;
name a, b;
begin
ref (C) temp :- a;
a :- b;
b :- t;
end

swap (x, y) работать будет обменивая местами значения двух переменных, ссылающихся на объекты. А вот если словечно name убрать - получится как раз семантика Java - и функция swap не будет делать ничего.

Я еще раз повторяю - это (включая терминологию) азы.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 23:14 (ссылка)
"представляются ссылочными значениями и эти значения передаются по значению, а не по ссылке."
Перестань взрывать мне мозг, пожалуйста.

Есть у тебя значение. "абвгд".
Оно лежит по определенному адресу в памяти - 0xabcabca.
Если мы передаем в метод "абвгд" - мы передали параметр по значению.
Если мы передаем в метод 0xabcabca - мы передали параметр по ссылке.
Если мы выделили ещё кусок памяти в 0xbcdbcdbc, записали туда 0xabcabca, и передали его - то мы передали параметр по двойной (непрямой, indirect) ссылке, но это надо отдельно обговаривать.

Я повторяю: "In call-by-reference evaluation, a function receives an implicit reference to the argument, rather than a copy of its value. This typically means that the function can modify the argument, what will be seen by its caller" вот это определение в Java выполняется.

Java is a call-by-value language, but since the results of most Java expressions are references to anonymous objects, it frequently displays call-by-reference semantics without the need for any explicit reference syntax.
Это именно то, о чем я говорил - в языке Java объекты при вызове метода передаются всегда по ссылке.
Причем в этой цитате мне совершенно непонятно "frequently" - в языке Java call-by-reference происходит всегда, кроме случая, когда аргумент - примитивный тип.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 23:41 (ссылка)
Причем в этой цитате мне совершенно непонятно "frequently" - в языке Java call-by-reference происходит всегда, кроме случая, когда аргумент - примитивный тип.


Еще раз - предлагаю написать в Java аналог приведенной функции swap.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 23:54 (ссылка)
Я не понимаю, как из определения call-by-reference следует возможность написать на таком языке swap.

Можно цитату, пожалуйста?

(Ответить) (Уровень выше)


[info]alamar
2009-04-08 23:59 (ссылка)
Ну и да
public class MutableInt {
public int value;
public MutableInt copy() {
MutableInt retval = new MutableInt();
retval.value = value;
return retval;
}
public void set(MutableInt from)
{
value = from.value;
}
}

void swap(MutableInt a, MutableInt b) {
MutableInt temp = a.copy();
a.set(b);
b.set(temp);
}


Нет? :)

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-09 01:04 (ссылка)
Нет-нет -

void m () {
  C x = new C (...);
  C y = new C (...);
  swap (x, y);
  ...
}


и чтобы работало.

Ну как в С++ будет несложно написать swap так чтобы работало
void m () {
  C * x = new C (...);
  C * y = new C (...);
  swap (x, y);
  ...
}

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 01:09 (ссылка)
void m () {
C x = new C (...);
C y = new C (...);
swap (x, y);
...
}
Имеешь в виду, что С - любой тип?

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

И в языках типа С++ передача по ссылке точно так же работает.
Только там есть copy constructorы.

Так вот, в C# struct отличается от classа в основном наличием конструктора копирования - то есть, вместо присвоения ссылки происходит копирование полей.

Что я упускаю?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-09 01:12 (ссылка)
Нет-нет - совершенно конкретный.

То есть swap (a, b) должно быть просто эквивалентно написанному руками соотвествующему коду.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 01:18 (ссылка)
Какой? Я такого класса не знаю.

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

Ты спрашиваешь, как поменять местами два значения. Я тебе рассказываю - через copy constructor или рефлексию. Что не устраивает?

Ты на мой вопрос про две цитаты-то ответишь?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-09 01:21 (ссылка)
Я говорю следующее - swap (a, b) должно быть эквивалетно рукописному коду

{
C t = a;
a = b;
b = t;
}

Где t - имя не совпадающее с a и b и a и b - имена переменных, а не выражения (последнее требование избыточно - но для простоты).

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 01:38 (ссылка)
Что значит - эквивалентно? Я не понимаю этого совсем.

Какие критерии эквивалентности?
Условие "содержимое объекта а до преобразования тождественно содержимому объекта б после преобразования, содержимое объекта б до преобразования тождественно содержимому объекта а после преобразования" достаточно?
Или есть ещё какие-то условия?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-09 01:39 (ссылка)
В смысле текстуальной подстановки одного вместо другого.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 01:47 (ссылка)
Не понял?
Ты хочешь, чтобы конкретно этот синтаксис работал?

Поздравляю, твой синтаксис не работает в жаве.
Это определение такое - "swap должен работать, и должен работать именно тем способом, который выбит на священных скрижалях"? Яебу.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-09 01:53 (ссылка)
Замена оператора swap (a, b); на
{ C t = a; a = b; b = t; } где а и b - переменные типа С, и их имя не совпадает с переменной t не должно никак изменять поведение программы (то есть не должно быть способов обнаружить факт этой замены штатными языковыми средствами), за исключением вопросов, связанных с временем исполнения.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 02:19 (ссылка)
Ну так я напишу такой swap.
Внутри swap(a, b) я все поля из a скопирую во временный объект, все поля из b - в а, а из временного объекта - в a.

Рефлексией!

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

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 02:19 (ссылка)
"а из временного объекта - в b."

(Ответить) (Уровень выше)


[info]kouzdra
2009-04-09 02:25 (ссылка)
Hint:

С a = new C (...);
C b = new C (...)
C c = a;
swap (a, b);
System.out.println (c == a);

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 02:55 (ссылка)
== сравнивает ссылки.

В таком же примере с языком С надо писать if(&c == &a), и оно будет всегда false. Хотя, должен признать, и со swap(), и со SWAP() - всё одно, false.

Разница есть, я согласен: но она не в передаче параметров в функцию (которая осуществляется одинаково), а в обращении с объектами внутри функции (которое разнится в случае С++ и Java).
это
http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
но я не готов назвать это call-by-value, потому что
mutations to those objects within the function are visible to the caller, which differs from call-by-value semantics.

Как я показал в параллельном длинном комментарии: разница эта существует внутри функции, но при вызове она как раз исчезает, и в вызываемую функцию приезжает ссылка. На объект.
Мне кажется, именно это важно с точки зрения семантики.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-09 15:08 (ссылка)
Я не буду вам ничего доказывать.
Преступник должен сидеть в тюрьме.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 21:12 (ссылка)
Так вот, я вчера под завершение пришел к выводу, что мы оба были неправы в том, что говорили.
Причина заключалась в том, что мы рассматривали вопрос о передаче параметров при вызове функции, но оказалось, что передача параметров в функции - это следствие, и никакой собственной свободы выбора она не имеет.

А причиной являются стратегии владения значениями.

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

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

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

Впрочем, я боюсь, вам это совершенно неинтересно, как неинтересна суть вычислений вообще.
Рад буду ошибиться.

(Ответить) (Уровень выше)


[info]zabivator
2009-04-28 01:15 (ссылка)
Извините, что вмешиваюсь - но есть пара вопросов.
swap, описанный вами может иметь три реализации

void swap( C*& a_left, C*& a_right )
{
C* temp = a_left;
a_right = a_left;
a_left = temp;
}

либо

void swap( C* a_left, C* a_right )
{
a_left->swap( a_right );
}

либо

void swap( C* a_left, C* a_right )
{
C temp( *a_left );
*a_left = *a_right;
*a_right = temp;
}

Т.е. разница в том, меняем мы местами указатели, или собственно сами значения по этим указателям.
Первое - унифицировано, т.е. не зависит от типов данных. В Джава и СиШарп нету значения
Второе - типоспецифично, требует поддержки со стороны каждого типа данных.
Третье - требует конструктора копирования (а его как я понял из треда в Джава и Сишарп нету, за исключением struct в СиШарпе) - но проблема даже не в этом, проблема не в этом (можно обойтись clone()) - новый объект будет присвоен ЛОКАЛЬНОМУ УКАЗАТЕЛЮ, а переданный извне не измениться (будет ссылаться на старый объект).

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

Т.е. всегда работает второй вариант - и мы передаем значения указателей на объекты (именно что указатели, т.к. они могут иметь значение null - и в этом смысле (valid value) ничем не отличаются от cишных и плюсовых указателей).
Это верные рассуждения?

Если я где-то ошибся - поясните что я пропустил, пожалуйста.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]zabivator
2009-04-28 01:17 (ссылка)
Первое - унифицировано, т.е. не зависит от типов данных. В Джава и СиШарп нету значения
нету ссылок на указатели, т.е. поменять местами их не выходя за пределы функции нельзя

(Ответить) (Уровень выше)


[info]zabivator
2009-04-28 01:26 (ссылка)
Естественно, в примере выше ошибка:

void swap( C*& a_left, C*& a_right )
{
C* temp = a_left;
a_right = a_left;
a_left = temp;

a_left = a_right;
a_right = temp;
}

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-28 02:14 (ссылка)
Все еще запутаннее - call-by-name предполагает вычисление аргумента каждый раз. Но я все-таки по этому поводу сейчас попытаюсь настроить Джаббера. До сих пор как-то бог миловал :)

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]zabivator
2009-04-28 02:15 (ссылка)
Если брать Psi и Gmail - "Использовать существующий аккаунт" -> "JID=mailname@gmail.com", "Server=talk.google.com", "Шифрование=если возможно"

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-28 02:17 (ссылка)
У меня нет аккаунта на gmail - и не предвидится. Но я думаю, сейчас победю.

(Ответить) (Уровень выше)


[info]zabivator
2009-04-28 02:16 (ссылка)
Извините за неудобства с джаберром - аська просто валится вечно =(
Можно скайп взять, можно email - смотрите как Вам удобней.
Большое спасибо.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-28 02:22 (ссылка)
Я собственно скорее даже за поиграться с IM - просто я попробовал его поставить - apt повис, а время уже позднее - давайте отложим до завтра-послезавтра.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]zabivator
2009-04-28 02:24 (ссылка)
Без проблем, можно по комментариям. http://lj.rossia.org/users/kouzdra/630759.html?thread=4148199#t4148199 Тут всё верно?

(Ответить) (Уровень выше)


[info]zabivator
2009-04-28 02:22 (ссылка)
Так, стоп, кажется я догоняю.
Для каждого отдельного скоупа (пространства имён) есть грубо говоря ассоциативный массив Имя" -> "адрес в памяти на объект".
a = new C() связывает с "a" адрес возвращённый new C(). А ещё точнее - new C() возвращает пару ("безымянный объект номер ХХХ",адрес2) а в операторе присваивания происходит замена в таблице (a,адрес1) на (a,адрес2).
Таким образом при обращении по имени call-by-value означает сходить в таблицу и достать значение адреса для данного имени. Это верные рассуждения?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-28 02:28 (ссылка)
call-by-value - это стандартное С/Java способ передачи параметров.

сall-by-refrence - это в первом приближении VAR паскаля, & С++ etc.

call-by-name - это вышедший из употребления, однако оказавший очень серьезное влияние метод, когда передается адрес процедуры вычисления значения параметра/присваивания ему значения - своего рода протоленивость.

Характерный пример - прием Йенсена

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]zabivator
2009-04-28 02:37 (ссылка)
call-by-name - это вышедший из употребления, однако оказавший очень серьезное влияние метод, когда передается адрес процедуры вычисления значения параметра/присваивания ему значения - своего рода протоленивость.
Эта хрень мне очень сильно напоминает hof.
А неотличимость hof и обычных функций задарма не получишь... требуется контекст (опционально пустой) либо рантайм-кодогенерация.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-28 02:44 (ссылка)
Это как раз не hof - в том и смысл (как и VAR и ref/out С#) - scope процедуры/ссылки жестко фиксируется - и появление висячих ссылок невозмонжо в принципе. Достаточно не замыкания, а просто ссылок в стек. Потому можно не заводить объекты в куче и вообще - не нуждаться в сборке мусора.

Собствеено MSIL тем от JVM и отличается, что многие вопросы такого рода адресует. В Cyclone это формализовать попытались в виде regions. Получился наворот мрачный - но идея в принципе работает.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]zabivator
2009-04-28 02:49 (ссылка)
Ммм. Вроде понимаю, но есть вопросы - вот этот самый term - это что?
Это адрес на точку входа в функцию (Си-смысл)?
Каким именно образом происходит связывание term и его аргументов?

(Ответить) (Уровень выше)


[info]alamar
2009-04-09 02:14 (ссылка)
Попробую медленно подойти с чистого листа.

С чего вообще ты придумал термин "ссылочное значение"? Зачем оно? Оно лишнее, бритва отрезає.

Существует объект. Он находится в куче.
У нас есть на него ссылка. Мы ей оперируем.

Мы вызываем метод. Этому методу мы отдаем ссылку. На объект.
А раз мы методу передаем ссылку. На объект.
То давай будем считать, что объект передаётся по ссылке.
Потому что мы ее передаем. На объект.


Твоя позиция строится на том, что ссылку-то мы "передаем по значению" - не берем в момент вызова метода ссылку на эту ссылку, а отдаём, как она есть.
Но мне кажется, что это усложнение не выдержит бритвы.
Дело в том, что ссылку можно передать по значению, но *ссылку нельзя передать по ссылке*.
Потому что передача ссылки на ссылку не является передачей объекта, слишком непрямая эта операция. Indirection слишком много.

Итак, у нас есть четыре варианта:
в таблице двое на двое
Что у нас было
Что мы с ним сделали

Варианты:
1) У нас было значение, мы его просто отдали.
2) У нас была ссылка, мы ее просто отдали.
3) У нас было значение, мы взяли с него ссылку и отдали ее.
4) У нас была ссылка, мы взяли с нее ссылку и отдали ее.

Очевидно, что второй и третий вариант, с точки зрения вызывающего, тождественен - ему передается ссылка. В С, собственно, это разница между
2)
int *i;
fscanf("%d", i);
и
3)
int i;
fscanf("%d", &i);
но с точки зрения вызываемого разницы нет.

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


Таким образом, кажется, я доказал, что в языке Java методы получают объекты-параметры исключительно по ссылке. Поскольку получают ссылку на оный объект-параметр.

Можно принять другой вариант терминологии, например, как в статье, про http://javadude.com/articles/passbyvalue.htm
Но мне не кажется, что эта терминология чем-то лучше предложенной.
Ну и с определением, взятым из википедии, мой вариант совпадает.

(Ответить) (Уровень выше)


[info]kouzdra
2009-04-08 23:00 (ссылка)
А также обвинял меня в некомпетентности на основании своего спора с моим истинным высказыванием, тем самым вторгнувшись в страну анального говноедства

PS: Довольно точным аналогом предыдущего постинга является объяснение почему в подинтегральной формуле x/dx нельзя сократить на x

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-09 01:20 (ссылка)
"почему в подинтегральной формуле x/dx нельзя сократить на x"
Тоже мне бином ньютона.

Потому что это херовая форма записи.
И она вызывает вопросы.
Которых могла бы не вызывать, если бы не была херовой.

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

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

(Ответить) (Уровень выше)


[info]kouzdra
2009-04-08 22:42 (ссылка)
PS: Пожалуй дам хинт - передача значения по ссылке и передача ссылки как значения - две большие и разные разницы (хотя до определенной степени родственные).

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 22:53 (ссылка)
Ты жонглируешь терминологией, как в дешевом балагане.

Я цитат жду, потому что их обычно вменяемые люди пишут, других не цитируют.

Я повторяю тебе - в жаве. все объекты. передаются в методы. по ссылке.
С каким из этих слов ты не согласен?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 23:11 (ссылка)
Как бе советую перестать позориться и почитать книжки - я уже начал пиарить сей дивный тред.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 23:16 (ссылка)
Пожалуйста.
Я тоже попиарю.

(Ответить) (Уровень выше)


[info]alamar
2009-04-08 22:28 (ссылка)
Далее:
"то не понимает, как реализуются замыкания (частным случаями которых являются и делегаты и анонимные классы Java),"
Попробуй изобразить на яве type-safe delegates.
С вараргами и проверкой сигнатур на этапе компиляции.
Я с удовольствием посмотрю.

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

Потому что interface Runnable { Object run(Object[] parameters); } - это не делегаты, это говно.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 22:36 (ссылка)
Значит все-таки устраивать ликбез: берем пример:

public delegate int ButtonClickHandler (object obj1, object obj2)


Тип, ему соотвествующий:

abstract class ButtonClickHandler {
  public abstract int run (object obj1, object obj2);
}


Можно дальше не объяснять?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 22:59 (ссылка)
Честно скажу, я пока не могу придумать случая, чтобы при такой трансляции делегатов type safety была нарушена.
Мне казалось, такие случаи могут быть.
Возможно, здесь я неправ был.

(Ответить) (Уровень выше)


[info]alamar
2009-04-08 22:38 (ссылка)
Далее:
"реализация языка программирования должна реализоваывать его полностью - вне зависимости от мнения о полезности его фич."
Попробуй изобразить в JRuby такой замечательный класс, как ObjectSpace.
При этом - вполне себе реализация.

Однако, ты осуществляешь очередной спин, утверждая, что я "не понимаю, что реализация языка программирования должна реализовывать его полностью".
Дело в том, что я нигде такого не говорил.
Я говорил:
"struct не нужен"
Его можно, понятно, реализовать в JVM без каких-либо проблем с полным сохранением поведения. Но это не делает его более полезным, честно говоря. Но я никогда не говорил, что его нельзя реализовать, и не говорил, что его не надо реализовывать. Если делаешь C# - реализовать надо, пользоваться - не стоит.

Кончай приписывать мне свой бред.
Я был о тебе куда как лучшего мнения.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]kouzdra
2009-04-08 22:45 (ссылка)
Говорилось:

Что в C# такого, что сложно оттранслировать в JVM?
struct? struct не нужен.


Нужен или нет - дело десятое (на мой взгляд весьма полезен - особенно в vm с претензией на мультиязыковость - потому как распространненная очень вещь) - но он там есть - и потому C# сложно оттранслировать в JVM.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]alamar
2009-04-08 23:01 (ссылка)
В чём конкретно заключаются сложности трансляции structов в JVM?

То есть, я могу представить себе сложности их использования в JVM, но вне C#; но если это будет внутриC#овый феномен, то в чём вообще проблема?

(Ответить) (Уровень выше)


[info]potan
2009-04-09 14:02 (ссылка)
то не понимает, что реализация языка программирования должна реализоваывать его полностью - вне зависимости от мнения о полезности его фич. etc etс.
Как то в рассылке по языку Mercury я спросил, почему моя программа не компилируется. Мне ответили - не надо путать язык и его реализацию. (В продолжении дисскуссии выяснилось, что была версия языка с поддержкой использованной мной фичи, но она оказалась сильно медленнее даже на программах, эту фичу не использующих.)

(Ответить) (Уровень выше)


(Читать комментарии) -