<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://pascalabc.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Juliet</id>
	<title>Вики проекта PascalABC.NET - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://pascalabc.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Juliet"/>
	<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Juliet"/>
	<updated>2026-04-18T10:47:07Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2714</id>
		<title>Начало. Возможные ошибки</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2714"/>
		<updated>2014-09-20T06:57:01Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Отсутствие закрывающего апострофа литеральной строки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=== Неописанная переменная ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  S := 1; // Неизвестное имя S&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Все используемые переменные должны быть предварительно описаны в разделе описаний. В PascalABC.NET допускаются также описания переменных внутри блока.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующая ; ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer // Ожидалась ;&lt;br /&gt;
  S := 1; &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1 // Ожидалась ;&lt;br /&gt;
  S := S + 1&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Очень частая ошибка у начинающих. Курсор, как правило, позиционируется в начале следующей строки&lt;br /&gt;
&lt;br /&gt;
=== Несовместимость типов при присваивании ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1.3; // Нельзя преобразовать тип real к integer&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Безболезненно можно присваивать только данные одного типа. Если данные - разных типов, то в редких случаях можно преобразовать данные одного типа в данные другого. Например, целое можно преобразовать в вещественное, а символ - в строку. Обратные преобразования не допускаются.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствие закрывающего апострофа литеральной строки ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x := 2;   // x получает тип integer&lt;br /&gt;
  var y := 3;   // y получает тип integer&lt;br /&gt;
  writeln('Результат сложения равен =, x + y); // Не хватает закрывающего апострофа&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Закрыть апостроф надо на той же строке, где расположен открывающий апостроф&lt;br /&gt;
&lt;br /&gt;
=== Ошибки расстановки запятых и апострофов при выводе строк и выражений ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x := 2;   // x получает тип integer&lt;br /&gt;
  var y := 3;   // y получает тип integer&lt;br /&gt;
  writeln(x, '+,' y, '=', x+y); // Неверная расстановка запятых и апострофов&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Слишком много запятых и апострофов рядом, потому начинающие часто путаются :) &lt;br /&gt;
Надо уяснить правила: &lt;br /&gt;
*запятые разделяют разные элементы вывода&lt;br /&gt;
*все, что находится в апострофах, будет выведено на экран без изменений&lt;br /&gt;
&lt;br /&gt;
=== Ошибка ввода ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  read(x); // введите блаблабла и посмотрите, что получится&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Это - ошибка во время выполнения. Программа пытается преобразовать введенную строку в число, не может это сделать и завершается с ошибкой&lt;br /&gt;
&lt;br /&gt;
=== Ошибка неинициализированной переменной ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  // Забыли инициализировать или ввести x&lt;br /&gt;
  var r := x * x;  // r получает тип integer&lt;br /&gt;
  writeln('Квадрат числа ', x, ' = ', r);&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Перед использованием любую переменную надо ввести или присвоить ей начальное значение. Это действие называется инициализацией переменной.&lt;br /&gt;
&lt;br /&gt;
=== Деление на 0 ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer := 0;&lt;br /&gt;
  var c: integer := 666 div x; // Здесь происходит деление на 0&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Если во время выполнения программа выполнит деление на 0, то она завершится с ошибкой.&lt;br /&gt;
&lt;br /&gt;
=== Корень из отрицательного числа ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  writeln(sqrt(-1)); // Корень из отрицательного числа &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
В обычном Паскале возникает ошибка времени выполнения. &lt;br /&gt;
В PascalABC.NET выводится NaN - Not a Number&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
*[[Программы для начинающих]]&lt;br /&gt;
*[http://pascalabc.net/ru/programmyi-i-algoritmyi-dlya-nachinayuschih.html Сайт PascalABC.NET: Программы и алгоритмы для начинающих]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2713</id>
		<title>Начало. Возможные ошибки</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2713"/>
		<updated>2014-09-20T06:56:48Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Ошибки расстановки запятых и апострофов при выводе строк и выражений */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=== Неописанная переменная ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  S := 1; // Неизвестное имя S&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Все используемые переменные должны быть предварительно описаны в разделе описаний. В PascalABC.NET допускаются также описания переменных внутри блока.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующая ; ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer // Ожидалась ;&lt;br /&gt;
  S := 1; &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1 // Ожидалась ;&lt;br /&gt;
  S := S + 1&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Очень частая ошибка у начинающих. Курсор, как правило, позиционируется в начале следующей строки&lt;br /&gt;
&lt;br /&gt;
=== Несовместимость типов при присваивании ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1.3; // Нельзя преобразовать тип real к integer&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Безболезненно можно присваивать только данные одного типа. Если данные - разных типов, то в редких случаях можно преобразовать данные одного типа в данные другого. Например, целое можно преобразовать в вещественное, а символ - в строку. Обратные преобразования не допускаются.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствие закрывающего апострофа литеральной строки ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x, y: integer;&lt;br /&gt;
  x := 2; &lt;br /&gt;
  y := 3;&lt;br /&gt;
  writeln('Результат сложения равен =, x + y); // Не хватает закрывающего апострофа&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Закрыть апостроф надо на той же строке, где расположен открывающий апостроф&lt;br /&gt;
&lt;br /&gt;
=== Ошибки расстановки запятых и апострофов при выводе строк и выражений ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x := 2;   // x получает тип integer&lt;br /&gt;
  var y := 3;   // y получает тип integer&lt;br /&gt;
  writeln(x, '+,' y, '=', x+y); // Неверная расстановка запятых и апострофов&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Слишком много запятых и апострофов рядом, потому начинающие часто путаются :) &lt;br /&gt;
Надо уяснить правила: &lt;br /&gt;
*запятые разделяют разные элементы вывода&lt;br /&gt;
*все, что находится в апострофах, будет выведено на экран без изменений&lt;br /&gt;
&lt;br /&gt;
=== Ошибка ввода ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  read(x); // введите блаблабла и посмотрите, что получится&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Это - ошибка во время выполнения. Программа пытается преобразовать введенную строку в число, не может это сделать и завершается с ошибкой&lt;br /&gt;
&lt;br /&gt;
=== Ошибка неинициализированной переменной ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  // Забыли инициализировать или ввести x&lt;br /&gt;
  var r := x * x;  // r получает тип integer&lt;br /&gt;
  writeln('Квадрат числа ', x, ' = ', r);&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Перед использованием любую переменную надо ввести или присвоить ей начальное значение. Это действие называется инициализацией переменной.&lt;br /&gt;
&lt;br /&gt;
=== Деление на 0 ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer := 0;&lt;br /&gt;
  var c: integer := 666 div x; // Здесь происходит деление на 0&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Если во время выполнения программа выполнит деление на 0, то она завершится с ошибкой.&lt;br /&gt;
&lt;br /&gt;
=== Корень из отрицательного числа ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  writeln(sqrt(-1)); // Корень из отрицательного числа &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
В обычном Паскале возникает ошибка времени выполнения. &lt;br /&gt;
В PascalABC.NET выводится NaN - Not a Number&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
*[[Программы для начинающих]]&lt;br /&gt;
*[http://pascalabc.net/ru/programmyi-i-algoritmyi-dlya-nachinayuschih.html Сайт PascalABC.NET: Программы и алгоритмы для начинающих]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2712</id>
		<title>Начало. Возможные ошибки</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2712"/>
		<updated>2014-09-20T06:56:10Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Деление на 0 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=== Неописанная переменная ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  S := 1; // Неизвестное имя S&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Все используемые переменные должны быть предварительно описаны в разделе описаний. В PascalABC.NET допускаются также описания переменных внутри блока.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующая ; ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer // Ожидалась ;&lt;br /&gt;
  S := 1; &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1 // Ожидалась ;&lt;br /&gt;
  S := S + 1&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Очень частая ошибка у начинающих. Курсор, как правило, позиционируется в начале следующей строки&lt;br /&gt;
&lt;br /&gt;
=== Несовместимость типов при присваивании ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1.3; // Нельзя преобразовать тип real к integer&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Безболезненно можно присваивать только данные одного типа. Если данные - разных типов, то в редких случаях можно преобразовать данные одного типа в данные другого. Например, целое можно преобразовать в вещественное, а символ - в строку. Обратные преобразования не допускаются.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствие закрывающего апострофа литеральной строки ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x, y: integer;&lt;br /&gt;
  x := 2; &lt;br /&gt;
  y := 3;&lt;br /&gt;
  writeln('Результат сложения равен =, x + y); // Не хватает закрывающего апострофа&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Закрыть апостроф надо на той же строке, где расположен открывающий апостроф&lt;br /&gt;
&lt;br /&gt;
=== Ошибки расстановки запятых и апострофов при выводе строк и выражений ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x, y: integer;&lt;br /&gt;
  x := 2; &lt;br /&gt;
  y := 3;&lt;br /&gt;
  writeln(x, '+,' y, '=', x+y); // Неверная расстановка запятых и апострофов&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Слишком много запятых и апострофов рядом, потому начинающие часто путаются :) &lt;br /&gt;
Надо уяснить правила: &lt;br /&gt;
*запятые разделяют разные элементы вывода&lt;br /&gt;
*все, что находится в апострофах, будет выведено на экран без изменений&lt;br /&gt;
&lt;br /&gt;
=== Ошибка ввода ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  read(x); // введите блаблабла и посмотрите, что получится&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Это - ошибка во время выполнения. Программа пытается преобразовать введенную строку в число, не может это сделать и завершается с ошибкой&lt;br /&gt;
&lt;br /&gt;
=== Ошибка неинициализированной переменной ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  // Забыли инициализировать или ввести x&lt;br /&gt;
  var r := x * x;  // r получает тип integer&lt;br /&gt;
  writeln('Квадрат числа ', x, ' = ', r);&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Перед использованием любую переменную надо ввести или присвоить ей начальное значение. Это действие называется инициализацией переменной.&lt;br /&gt;
&lt;br /&gt;
=== Деление на 0 ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer := 0;&lt;br /&gt;
  var c: integer := 666 div x; // Здесь происходит деление на 0&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Если во время выполнения программа выполнит деление на 0, то она завершится с ошибкой.&lt;br /&gt;
&lt;br /&gt;
=== Корень из отрицательного числа ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  writeln(sqrt(-1)); // Корень из отрицательного числа &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
В обычном Паскале возникает ошибка времени выполнения. &lt;br /&gt;
В PascalABC.NET выводится NaN - Not a Number&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
*[[Программы для начинающих]]&lt;br /&gt;
*[http://pascalabc.net/ru/programmyi-i-algoritmyi-dlya-nachinayuschih.html Сайт PascalABC.NET: Программы и алгоритмы для начинающих]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2711</id>
		<title>Начало. Возможные ошибки</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9D%D0%B0%D1%87%D0%B0%D0%BB%D0%BE._%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8&amp;diff=2711"/>
		<updated>2014-09-20T06:55:28Z</updated>

		<summary type="html">&lt;p&gt;Juliet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=== Неописанная переменная ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  S := 1; // Неизвестное имя S&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Все используемые переменные должны быть предварительно описаны в разделе описаний. В PascalABC.NET допускаются также описания переменных внутри блока.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующая ; ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer // Ожидалась ;&lt;br /&gt;
  S := 1; &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1 // Ожидалась ;&lt;br /&gt;
  S := S + 1&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Очень частая ошибка у начинающих. Курсор, как правило, позиционируется в начале следующей строки&lt;br /&gt;
&lt;br /&gt;
=== Несовместимость типов при присваивании ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var S: integer := 1.3; // Нельзя преобразовать тип real к integer&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Безболезненно можно присваивать только данные одного типа. Если данные - разных типов, то в редких случаях можно преобразовать данные одного типа в данные другого. Например, целое можно преобразовать в вещественное, а символ - в строку. Обратные преобразования не допускаются.&lt;br /&gt;
&lt;br /&gt;
=== Отсутствие закрывающего апострофа литеральной строки ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x, y: integer;&lt;br /&gt;
  x := 2; &lt;br /&gt;
  y := 3;&lt;br /&gt;
  writeln('Результат сложения равен =, x + y); // Не хватает закрывающего апострофа&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Закрыть апостроф надо на той же строке, где расположен открывающий апостроф&lt;br /&gt;
&lt;br /&gt;
=== Ошибки расстановки запятых и апострофов при выводе строк и выражений ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x, y: integer;&lt;br /&gt;
  x := 2; &lt;br /&gt;
  y := 3;&lt;br /&gt;
  writeln(x, '+,' y, '=', x+y); // Неверная расстановка запятых и апострофов&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Слишком много запятых и апострофов рядом, потому начинающие часто путаются :) &lt;br /&gt;
Надо уяснить правила: &lt;br /&gt;
*запятые разделяют разные элементы вывода&lt;br /&gt;
*все, что находится в апострофах, будет выведено на экран без изменений&lt;br /&gt;
&lt;br /&gt;
=== Ошибка ввода ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  read(x); // введите блаблабла и посмотрите, что получится&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Это - ошибка во время выполнения. Программа пытается преобразовать введенную строку в число, не может это сделать и завершается с ошибкой&lt;br /&gt;
&lt;br /&gt;
=== Ошибка неинициализированной переменной ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer;&lt;br /&gt;
  // Забыли инициализировать или ввести x&lt;br /&gt;
  var r := x * x;  // r получает тип integer&lt;br /&gt;
  writeln('Квадрат числа ', x, ' = ', r);&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Перед использованием любую переменную надо ввести или присвоить ей начальное значение. Это действие называется инициализацией переменной.&lt;br /&gt;
&lt;br /&gt;
=== Деление на 0 ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;var x,c: integer;&lt;br /&gt;
begin&lt;br /&gt;
  var x: integer := 0;&lt;br /&gt;
  var c: integer := 666 div x; // Здесь происходит деление на 0&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Если во время выполнения программа выполнит деление на 0, то она завершится с ошибкой.&lt;br /&gt;
&lt;br /&gt;
=== Корень из отрицательного числа ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;begin&lt;br /&gt;
  writeln(sqrt(-1)); // Корень из отрицательного числа &lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
В обычном Паскале возникает ошибка времени выполнения. &lt;br /&gt;
В PascalABC.NET выводится NaN - Not a Number&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
*[[Программы для начинающих]]&lt;br /&gt;
*[http://pascalabc.net/ru/programmyi-i-algoritmyi-dlya-nachinayuschih.html Сайт PascalABC.NET: Программы и алгоритмы для начинающих]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2615</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2615"/>
		<updated>2013-06-18T15:02:18Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* .NET generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер. Если не ошибаюсь, в Scala сделано то же самое.&lt;br /&gt;
&lt;br /&gt;
Сами дженерики NET компилируются в код Microsoft intermediate language (MSIL), где хранится метаинформация о типовых параметрах.&lt;br /&gt;
&lt;br /&gt;
В NET generics можно указать, что тип реализует несколько специализаций одного обобщенного интерфейса:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public class A : IEqComparable&amp;lt;A1&amp;gt;, IEqComparable&amp;lt;A2&amp;gt; {...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интерфейс может содержать обобщенный метод:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public interface IEqComparableGen&amp;lt;T&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	bool eqGen&amp;lt;S&amp;gt;(S y) where S : T;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно указывать зависимости между типовыми параметрами:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public static void algo1&amp;lt;T, U, S&amp;gt;(T x, U y, S z)&lt;br /&gt;
	where T : IComparable&amp;lt;T&amp;gt;&lt;br /&gt;
	where U : T&lt;br /&gt;
	where S : GenType&amp;lt;T&amp;gt;&lt;br /&gt;
{...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно описывать обобщённые делегаты:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public delegate void Delegate3&amp;lt;T&amp;gt;(T x) where T : struct;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Чего нет в сравнении с концептами ===&lt;br /&gt;
* ассоциированные типы;&lt;br /&gt;
* распространение ограничений;&lt;br /&gt;
* перегрузка на основе ограничений — следующее недопустимо:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public void p&amp;lt;S&amp;gt;(T x, S y) where S : class {...}&lt;br /&gt;
public void p&amp;lt;S&amp;gt;(T x, S y) where S : struct {...}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* в качестве типового параметра не может выступать обобщенный тип (конструктор типа).&lt;br /&gt;
&lt;br /&gt;
=== Полезные ссылки ===&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms172192.aspx Generics in the .NET Framework]&lt;br /&gt;
* [http://msmvps.com/blogs/jon_skeet/archive/2010/10/28/overloading-and-generic-constraints.aspx Про перегрузку в C#]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2614</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2614"/>
		<updated>2013-06-18T14:57:11Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* .NET generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер. Если не ошибаюсь, в Scala сделано то же самое.&lt;br /&gt;
&lt;br /&gt;
Сами дженерики NET компилируются в код Microsoft intermediate language (MSIL), где хранится метаинформация о типовых параметрах.&lt;br /&gt;
&lt;br /&gt;
В NET generics можно указать, что тип реализует несколько специализаций одного обобщенного интерфейса:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public class A : IEqComparable&amp;lt;A1&amp;gt;, IEqComparable&amp;lt;A2&amp;gt; {...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интерфейс может содержать обобщенный метод:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public interface IEqComparableGen&amp;lt;T&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	bool eqGen&amp;lt;S&amp;gt;(S y) where S : T;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно указывать зависимости между типовыми параметрами:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;CSharp&amp;quot;&amp;gt;&lt;br /&gt;
public static void algo1&amp;lt;T, U, S&amp;gt;(T x, U y, S z)&lt;br /&gt;
	where T : IComparable&amp;lt;T&amp;gt;&lt;br /&gt;
	where U : T&lt;br /&gt;
	where S : GenType&amp;lt;T&amp;gt;&lt;br /&gt;
{...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Полезные ссылки ===&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms172192.aspx Generics in the .NET Framework]&lt;br /&gt;
* [http://msmvps.com/blogs/jon_skeet/archive/2010/10/28/overloading-and-generic-constraints.aspx Про перегрузку в C#]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2613</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2613"/>
		<updated>2013-06-18T09:09:05Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Полезные ссылки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер. Если не ошибаюсь, в Scala сделано то же самое.&lt;br /&gt;
&lt;br /&gt;
Сами дженерики NET компилируются в код Microsoft intermediate language (MSIL), где хранится метаинформация о типовых параметрах.&lt;br /&gt;
&lt;br /&gt;
=== Полезные ссылки ===&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms172192.aspx Generics in the .NET Framework]&lt;br /&gt;
* [http://msmvps.com/blogs/jon_skeet/archive/2010/10/28/overloading-and-generic-constraints.aspx Про перегрузку в C#]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2612</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2612"/>
		<updated>2013-06-18T09:08:53Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Полезные ссылки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер. Если не ошибаюсь, в Scala сделано то же самое.&lt;br /&gt;
&lt;br /&gt;
Сами дженерики NET компилируются в код Microsoft intermediate language (MSIL), где хранится метаинформация о типовых параметрах.&lt;br /&gt;
&lt;br /&gt;
=== Полезные ссылки ===&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms172192.aspx Generics in the .NET Framework]&lt;br /&gt;
* [msmvps.com/blogs/jon_skeet/archive/2010/10/28/overloading-and-generic-constraints.aspx Про перегрузку в C#]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2611</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2611"/>
		<updated>2013-06-17T12:34:25Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* .NET generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер. Если не ошибаюсь, в Scala сделано то же самое.&lt;br /&gt;
&lt;br /&gt;
Сами дженерики NET компилируются в код Microsoft intermediate language (MSIL), где хранится метаинформация о типовых параметрах.&lt;br /&gt;
&lt;br /&gt;
=== Полезные ссылки ===&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/ms172192.aspx Generics in the .NET Framework]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2610</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2610"/>
		<updated>2013-06-17T12:32:28Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* .NET generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер. Если не ошибаюсь, в Scala сделано то же самое.&lt;br /&gt;
&lt;br /&gt;
Сами дженерики NET компилируются в код Microsoft intermediate language (MSIL), где хранится метаинформация о типовых параметрах.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2609</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2609"/>
		<updated>2013-06-17T12:31:15Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* .NET generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер. Если не ошибаюсь, в Scala сделано то же самое.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2608</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2608"/>
		<updated>2013-06-17T12:30:41Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* .NET generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»). &lt;br /&gt;
&lt;br /&gt;
При использовании обобщенного класса с типом-значением в рантайме генерируется соответствующая инстанция (своя для каждого типа-значения). А вот для всех ссылочных типов генерируется одна версия обобщенного класса, так как объекты-ссылки имеют одинаковый размер.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2607</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2607"/>
		<updated>2013-06-17T12:22:46Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* .NET generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;br /&gt;
&lt;br /&gt;
В NET дженерики другие, вот подходящая статья про их компиляцию: [http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx статья про компиляцию шаблонов NET на MSDN] («Generics in the Run Time (C# Programming Guide)»).&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2606</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2606"/>
		<updated>2013-06-17T12:20:48Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Java Generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== .NET generics ==&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2605</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2605"/>
		<updated>2013-06-14T10:57:52Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Использование объектов-моделей */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2604</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2604"/>
		<updated>2013-06-14T10:57:14Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Использование объектов-моделей */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y);&lt;br /&gt;
	public boolean neq(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharEqCmp cmpIC = new IntCharEqCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleEqCmp cmpID = new IntDoubleEqCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public boolean eq(T x, S y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(T x, S y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharEqCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Очевидным недостатком такого подхода является то, что в классе мы вынуждены реализовывать некоторые заглушки всех методов. А потом в наследнике невозможно проверить, был ли переопределен метод для конкретных типов.&lt;br /&gt;
&lt;br /&gt;
Вторая проблема — ''concept refinement''. Если обобщенный класс-концепт, улучшающий некоторый концепт, описать ещё можно (пример не имеет особого смысла, конечно):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class ComparableBasic&amp;lt;T, S&amp;gt; extends EqualityComparableBasic&amp;lt;T, S&amp;gt; {&lt;br /&gt;
	public int cmp(T x, S y) {&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
то как определять модель? У класса может быть только один предок. Поэтому, если мы определяем класс-модель, который наследует наш новый &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, придётся переопределять в нём как методы &amp;lt;code&amp;gt;ComparableBasic&amp;lt;/code&amp;gt;, так и &amp;lt;code&amp;gt;EqualityComparableBasic&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В случае с интерфейсами этой проблемы нет. Мы можем определить класс &amp;lt;code&amp;gt;IntDoubleCmp&amp;lt;/code&amp;gt; — наследник &amp;lt;code&amp;gt;IntDoubleEqCmp&amp;lt;/code&amp;gt; (реализует &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt;), который реализует &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Comparable&amp;lt;T, S&amp;gt; extends EqualityComparable&amp;lt;T, S&amp;gt;{&lt;br /&gt;
	public int cmp(T x, S y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp extends IntDoubleEqCmp implements Comparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public int cmp(Integer x, Double y) {&lt;br /&gt;
		return new Double(x.doubleValue()).compareTo(y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2603</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2603"/>
		<updated>2013-06-14T10:10:13Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Java Generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''стирание типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в результирующем коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за стирания типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы естественным образом реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт стирание типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование объектов-моделей ===&lt;br /&gt;
&lt;br /&gt;
Придётся использовать наши любимые объекты-концепты в обобщенном коде и объекты-модели — в конкретном.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface EqualityComparable&amp;lt;S, T&amp;gt; {&lt;br /&gt;
	public boolean eq(S x, T y);&lt;br /&gt;
	public boolean neq(S x, T y);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparable&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmp implements EqualityComparable&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Double y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharCmp implements EqualityComparable&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(Integer x, Character y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static void testEqCmp() {&lt;br /&gt;
	ArrayList&amp;lt;Integer&amp;gt; arr = new ArrayList&amp;lt;Integer&amp;gt;();&lt;br /&gt;
	// ...&lt;br /&gt;
	IntCharCmp cmpIC = new IntCharCmp();&lt;br /&gt;
	//Algos.contains(arr, new Double(3.14), cmpIC);	// ERROR&lt;br /&gt;
	IntDoubleCmp cmpID = new IntDoubleCmp();&lt;br /&gt;
	Algos.contains(arr, new Double(3.14), cmpID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом в обобщённый алгоритм нужно явно передавать объекты, которые реализуют нужный концепт. Похожим образом мы поступали и в Scala, но в отличие от Scala здесь есть ряд неприятных особенностей:&lt;br /&gt;
# интерфейс не может содержать реализации методов по умолчанию, поэтому во всех моделях &amp;lt;code&amp;gt;EqualityComparable&amp;lt;/code&amp;gt; приходится дублировать реализацию метода &amp;lt;code&amp;gt;neq&amp;lt;/code&amp;gt; (Scala traits допускают базовую реализацию).&lt;br /&gt;
# приходится описывать реализацию модели в конкретном классе, а потом создавать объект данного класса, чтобы передать его в вызов обобщенного алгоритма. В Scala для этой цели удобно использовать объект-наследник концепта (синглтон).&lt;br /&gt;
# любой концепт, который нам требуется, приходится передавать отдельным параметром. В Scala ситуацию спасают implisits, а здесь нам может потребоваться довольно большое число объектов-моделей, что весьма громоздко.&lt;br /&gt;
&lt;br /&gt;
Недостаток (1) можно обойти, если для концепта использовать обобщённый класс вместо обобщённого интерфейса. Тогда можно сделать в классе реализацию по умолчанию, а в наследниках переопределять только &amp;lt;code&amp;gt;eq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public class EqualityComparableBasic&amp;lt;S, T&amp;gt; {&lt;br /&gt;
	public boolean eq(S x, T y) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	public boolean neq(S x, T y) {&lt;br /&gt;
		return !eq(x, y);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static &amp;lt;T, S&amp;gt; boolean contains(Collection&amp;lt;T&amp;gt; elems, S x, EqualityComparableBasic&amp;lt;T, S&amp;gt; cmp) {&lt;br /&gt;
	boolean found = false;&lt;br /&gt;
	for (T t : elems) {&lt;br /&gt;
		if (cmp.eq(t, x)) {&lt;br /&gt;
			found = true;&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return found;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntDoubleCmpB extends EqualityComparableBasic&amp;lt;Integer, Double&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Double y) {&lt;br /&gt;
		return x.doubleValue() == y;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class IntCharCmpB extends EqualityComparableBasic&amp;lt;Integer, Character&amp;gt; {&lt;br /&gt;
	public boolean eq(Integer x, Character y) {&lt;br /&gt;
		return Character.getNumericValue(y) == x;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Однако&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2602</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2602"/>
		<updated>2013-06-13T16:08:08Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Java Generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''подчистка типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в подчищенном коде вместо &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за подчистки типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт подчистка типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2601</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2601"/>
		<updated>2013-06-13T16:07:36Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Java Generics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — ''подчистка типов''. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в подчищенном коде вместо &amp;lt;code&amp;gt;T стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за подчистки типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт подчистка типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2600</id>
		<title>Исследование обобщённого программирования</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%98%D1%81%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=2600"/>
		<updated>2013-06-13T16:07:22Z</updated>

		<summary type="html">&lt;p&gt;Juliet: Новая страница: «== Java Generics ==  Особенность Java Generics — подчистка типов. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслиру…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Java Generics ==&lt;br /&gt;
&lt;br /&gt;
Особенность Java Generics — подчистка типов. Обобщенный класс &amp;lt;code&amp;gt;A&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; транслируется в обычный класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, где везде вместо типа &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; используется &amp;lt;code&amp;gt;Object&amp;lt;/code&amp;gt;. Если на параметр типа есть ограничение, например, &amp;lt;code&amp;gt;A&amp;lt;T extends Comparable&amp;lt;T&amp;gt; &amp;gt;&amp;lt;/code&amp;gt;, то в подчищенном коде вместо &amp;lt;code&amp;gt;T стоит &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из-за подчистки типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?&lt;br /&gt;
&lt;br /&gt;
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт &lt;br /&gt;
&amp;lt;pre&amp;gt;Convertible&amp;lt;S, U&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
который содержит функцию &lt;br /&gt;
 U convert(S x)&lt;br /&gt;
или&lt;br /&gt;
 U S::convert()&lt;br /&gt;
&lt;br /&gt;
Можем ли мы реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здорово! Но мы хотим, чтобы класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; мог быть преобразован и в какой-нибудь &amp;lt;code&amp;gt;A2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Convertible&amp;lt;S&amp;gt; {&lt;br /&gt;
	public S convert();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class A1 {}&lt;br /&gt;
public class A2 {}&lt;br /&gt;
&lt;br /&gt;
public class A implements Convertible&amp;lt;A1&amp;gt;, Convertible&amp;lt;A2&amp;gt; {&lt;br /&gt;
	public A1 convert() {&lt;br /&gt;
		return new A1();&lt;br /&gt;
	}&lt;br /&gt;
	public A2 convert() {&lt;br /&gt;
		return new A2();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''А вот это уже не работает'''. Причина — ограничение '''[*]''', которое даёт подчистка типов. Класс &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; может реализовывать только какой-нибудь один &amp;lt;code&amp;gt;Convertible&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=2599</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=2599"/>
		<updated>2013-06-13T15:45:22Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Теория типов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Cтатьи==&lt;br /&gt;
* [[FAQ по PascalABC.NET]]&lt;br /&gt;
&lt;br /&gt;
== Примеры==&lt;br /&gt;
* [[Программы для начинающих|Программы и алгоритмы для начинающих]]&lt;br /&gt;
* [[Особенности языка: базовый уровень]]&lt;br /&gt;
* [[Стандартные модули: базовый уровень]]&lt;br /&gt;
* [[Особенности языка: продвинутый уровень]]&lt;br /&gt;
* [[Стандартные модули: продвинутый уровень]]&lt;br /&gt;
* [[Алгоритмы для студентов|Программы и алгоритмы для студентов ИТ]]&lt;br /&gt;
* [[Алгоритмы средней сложности]] (пока не реализовано)&lt;br /&gt;
&lt;br /&gt;
== Обучение==&lt;br /&gt;
* [[GPLex + GPPG|Задания по курсу &amp;quot;Методы построения компиляторов&amp;quot;]]&lt;br /&gt;
* [[Комплект юного разработчика парсеров]]&lt;br /&gt;
* [[Как создать компилятор]]&lt;br /&gt;
* [[Построение синтаксического дерева программы на языке Паскаль]]&lt;br /&gt;
* [[МПОК 2011]]&lt;br /&gt;
&lt;br /&gt;
== Web-среда разработки PascalABC.NET ==&lt;br /&gt;
&lt;br /&gt;
*[[Основная страница проекта WDE PascalABC.NET|Основная страница проекта]]&lt;br /&gt;
&lt;br /&gt;
==Другие проекты==&lt;br /&gt;
&lt;br /&gt;
* [[Идеи курсовых 2011]]&lt;br /&gt;
*[[Обзор реализации основных возможностей функционального языка программирования в среде PascalABC.NET|Проект &amp;quot;Реализация основных возможностей функционального языка программирования в среде PascalABC.NET&amp;quot; (Бушманова Н.)]]&lt;br /&gt;
*[[Рефакторинг|Проект &amp;quot;Рефакторинг по семантическому дереву PascalABC.NET&amp;quot; (Малеванный М., Коноплев Е.)]]&lt;br /&gt;
*[[Аспектно-ориентированное программирование|Проект &amp;quot;Аспектно-ориентированное программирование&amp;quot; (Зарубин М.)]]&lt;br /&gt;
* [[Реализация языка программирования Оберон на базе PascalABC.NET]]&lt;br /&gt;
&lt;br /&gt;
* [[Проект Optimus - учебная система оптимизации программ]]&lt;br /&gt;
&lt;br /&gt;
* [[Проект Megatron - оптимизирующий компилятор 2012 года]]&lt;br /&gt;
&lt;br /&gt;
== Для разработчика PascalABC.NET ==&lt;br /&gt;
&lt;br /&gt;
* [[Что менять при переходе к новой версии PascalABC.NET]]&lt;br /&gt;
* [[Архитектура PascalABC.NET]]&lt;br /&gt;
* [[Создание нового языка программирования - с чего начать]]&lt;br /&gt;
* [[Интерфейс подключения нового языка программирования|Интерфейс подключения нового языка программирования (проект)]]&lt;br /&gt;
* [[Директивы компилятора]]&lt;br /&gt;
* [[Синтаксическое дерево]]&lt;br /&gt;
* [[Семантическое дерево]]&lt;br /&gt;
* [[Формат PCU]]&lt;br /&gt;
* [[Отладчик]]&lt;br /&gt;
* [[Intellisense]]&lt;br /&gt;
* [[Шаблоны кода]]&lt;br /&gt;
* [[Создание нового стандартного модуля (для разработчика)]]&lt;br /&gt;
&lt;br /&gt;
== Статьи по программированию в PascalABC.NET ==&lt;br /&gt;
* [[Локализация приложений]]&lt;br /&gt;
* [[Плагины для PascalABC.NET]]&lt;br /&gt;
* [[Отслеживание изменений в файловой системе]]&lt;br /&gt;
* [[OpenGL]]&lt;br /&gt;
&lt;br /&gt;
== Теория типов ==&lt;br /&gt;
* [[Страничка семинара теории типов]]&lt;br /&gt;
* [[Исследование обобщённого программирования]]&lt;br /&gt;
&lt;br /&gt;
== Разное ==&lt;br /&gt;
* [[GPPG+GPLex - что исправить для русской кодировки]]&lt;br /&gt;
[[Ош]]&lt;br /&gt;
[[Ош1]]&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/docu/files/ScalaByExample.pdf Scala By example]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=2598</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=2598"/>
		<updated>2013-06-13T15:45:07Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Теория типов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Cтатьи==&lt;br /&gt;
* [[FAQ по PascalABC.NET]]&lt;br /&gt;
&lt;br /&gt;
== Примеры==&lt;br /&gt;
* [[Программы для начинающих|Программы и алгоритмы для начинающих]]&lt;br /&gt;
* [[Особенности языка: базовый уровень]]&lt;br /&gt;
* [[Стандартные модули: базовый уровень]]&lt;br /&gt;
* [[Особенности языка: продвинутый уровень]]&lt;br /&gt;
* [[Стандартные модули: продвинутый уровень]]&lt;br /&gt;
* [[Алгоритмы для студентов|Программы и алгоритмы для студентов ИТ]]&lt;br /&gt;
* [[Алгоритмы средней сложности]] (пока не реализовано)&lt;br /&gt;
&lt;br /&gt;
== Обучение==&lt;br /&gt;
* [[GPLex + GPPG|Задания по курсу &amp;quot;Методы построения компиляторов&amp;quot;]]&lt;br /&gt;
* [[Комплект юного разработчика парсеров]]&lt;br /&gt;
* [[Как создать компилятор]]&lt;br /&gt;
* [[Построение синтаксического дерева программы на языке Паскаль]]&lt;br /&gt;
* [[МПОК 2011]]&lt;br /&gt;
&lt;br /&gt;
== Web-среда разработки PascalABC.NET ==&lt;br /&gt;
&lt;br /&gt;
*[[Основная страница проекта WDE PascalABC.NET|Основная страница проекта]]&lt;br /&gt;
&lt;br /&gt;
==Другие проекты==&lt;br /&gt;
&lt;br /&gt;
* [[Идеи курсовых 2011]]&lt;br /&gt;
*[[Обзор реализации основных возможностей функционального языка программирования в среде PascalABC.NET|Проект &amp;quot;Реализация основных возможностей функционального языка программирования в среде PascalABC.NET&amp;quot; (Бушманова Н.)]]&lt;br /&gt;
*[[Рефакторинг|Проект &amp;quot;Рефакторинг по семантическому дереву PascalABC.NET&amp;quot; (Малеванный М., Коноплев Е.)]]&lt;br /&gt;
*[[Аспектно-ориентированное программирование|Проект &amp;quot;Аспектно-ориентированное программирование&amp;quot; (Зарубин М.)]]&lt;br /&gt;
* [[Реализация языка программирования Оберон на базе PascalABC.NET]]&lt;br /&gt;
&lt;br /&gt;
* [[Проект Optimus - учебная система оптимизации программ]]&lt;br /&gt;
&lt;br /&gt;
* [[Проект Megatron - оптимизирующий компилятор 2012 года]]&lt;br /&gt;
&lt;br /&gt;
== Для разработчика PascalABC.NET ==&lt;br /&gt;
&lt;br /&gt;
* [[Что менять при переходе к новой версии PascalABC.NET]]&lt;br /&gt;
* [[Архитектура PascalABC.NET]]&lt;br /&gt;
* [[Создание нового языка программирования - с чего начать]]&lt;br /&gt;
* [[Интерфейс подключения нового языка программирования|Интерфейс подключения нового языка программирования (проект)]]&lt;br /&gt;
* [[Директивы компилятора]]&lt;br /&gt;
* [[Синтаксическое дерево]]&lt;br /&gt;
* [[Семантическое дерево]]&lt;br /&gt;
* [[Формат PCU]]&lt;br /&gt;
* [[Отладчик]]&lt;br /&gt;
* [[Intellisense]]&lt;br /&gt;
* [[Шаблоны кода]]&lt;br /&gt;
* [[Создание нового стандартного модуля (для разработчика)]]&lt;br /&gt;
&lt;br /&gt;
== Статьи по программированию в PascalABC.NET ==&lt;br /&gt;
* [[Локализация приложений]]&lt;br /&gt;
* [[Плагины для PascalABC.NET]]&lt;br /&gt;
* [[Отслеживание изменений в файловой системе]]&lt;br /&gt;
* [[OpenGL]]&lt;br /&gt;
&lt;br /&gt;
== Теория типов ==&lt;br /&gt;
[[Страничка семинара теории типов]]&lt;br /&gt;
[[Исследование обобщённого программирования]]&lt;br /&gt;
&lt;br /&gt;
== Разное ==&lt;br /&gt;
* [[GPPG+GPLex - что исправить для русской кодировки]]&lt;br /&gt;
[[Ош]]&lt;br /&gt;
[[Ош1]]&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/docu/files/ScalaByExample.pdf Scala By example]&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2595</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2595"/>
		<updated>2013-02-21T18:36:23Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
16 страниц. &lt;br /&gt;
&lt;br /&gt;
Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Раз концепты есть, то как-то можно обеспечить концепт, связывающий два и более параметров шаблона. Как? &lt;br /&gt;
Может, в статье всё-таки ничего не говорится о концептах?&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Слова «концепты» в статье вообще нет, это правда. Есть пример моделирования классов типов Haskell.&lt;br /&gt;
&lt;br /&gt;
А связать несколько параметров можно, просто trait с несколькими параметрами.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
trait myTrait[S, T] {&lt;br /&gt;
  def convert(x: S): T&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Ну, это не очень - это и на C++ старом можно написать. А вот пример использования triats как концептов в новом C++ можно? В стиле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;template&amp;lt;InputIterator Iter, typename V&amp;gt;&lt;br /&gt;
requires EqualityComparable&amp;lt;Iter::value_type, V&amp;gt;&lt;br /&gt;
Iter find(Iter first, Iter last, V v) { &lt;br /&gt;
  while (first &amp;lt; last &amp;amp;&amp;amp; *first != v)&lt;br /&gt;
    ++first;&lt;br /&gt;
  return first;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
По идее можно, но я опять ничего не понимаю, пытаюсь написать...&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
В общем, у меня все печально. С value_type, спрятанным внутрь траита, совсем ничего не получается. Получился какой-то такой ужас:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
  trait EqualityComparable[S, T] {&lt;br /&gt;
  	def ==(s: S, t: T): Boolean&lt;br /&gt;
  	def !=(s: S, t: T): Boolean = !(s == t)&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  implicit object EqIntInt extends EqualityComparable[Int, Int] {&lt;br /&gt;
  	def ==(a: Int, b: Int): Boolean = { a == b }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  trait PInputIterator[value_type] {&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[value_type]): Boolean&lt;br /&gt;
  	def ++(): Unit&lt;br /&gt;
  	def *(): value_type&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  class IntNumber(x: Int) extends PInputIterator[Int]{&lt;br /&gt;
  	var n = x&lt;br /&gt;
  	&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[Int]): Boolean = {&lt;br /&gt;
  		val y = b.asInstanceOf[IntNumber];&lt;br /&gt;
  		n &amp;lt; y.n&lt;br /&gt;
  	}&lt;br /&gt;
  	def ++(): Unit = { n += 1; }&lt;br /&gt;
  	def *(): Int = n&lt;br /&gt;
  	&lt;br /&gt;
  	override def toString(): String = n.toString()&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  def pfind[X, Iter &amp;lt;: PInputIterator[X], V](first: Iter, last: Iter, v: V)&lt;br /&gt;
  		(implicit cmp: EqualityComparable[X, V]): Iter =&lt;br /&gt;
  {&lt;br /&gt;
    	while (first &amp;lt; last &amp;amp;&amp;amp; cmp.!=(first.*(), v))&lt;br /&gt;
    		first.++()&lt;br /&gt;
  	first&lt;br /&gt;
  }                                               //&amp;gt; pfind: [X, Iter &amp;lt;: concepts.iterator.PInputIterator[X], V](first: Iter, las&lt;br /&gt;
                                                  //| t: Iter, v: V)(implicit cmp: concepts.iterator.EqualityComparable[X,V])Iter&lt;br /&gt;
                                                  //| &lt;br /&gt;
  &lt;br /&gt;
  var c5 = new IntNumber(5)                //&amp;gt; c5  : concepts.iterator.IntNumber = 5&lt;br /&gt;
  var c15 = new IntNumber(15)              //&amp;gt; c15  : concepts.iterator.IntNumber = 15&lt;br /&gt;
  val d11 = pfind[Int, IntNumber, Int](c5, c15, 11)&lt;br /&gt;
                                                  //&amp;gt; d11  : concepts.iterator.IntNumber = 11&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причем ''не указывать'' параметры при вызове pfind не получается, ошибка: &amp;lt;tt&amp;gt;Type inferred type arguments [Nothing,IntNumber,Int] do not conform to method pfind's type parameter bounds [X,Iter &amp;lt;: PInputIterator[X],V]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Я снова открыла статью, про которую Артем на семинаре докладывал. Она несколько нивелировала влияние статьи «Generics of a Higher Kind». Теперь у меня вот так получилось (добраться до внутреннего типа все равно никак не получается):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
trait EqualityComparable[S, T] {&lt;br /&gt;
	def ==(s: S, t: T): Boolean&lt;br /&gt;
  	def !=(s: S, t: T): Boolean = !(s == t)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trait InputIterator[Iter] {&lt;br /&gt;
	type value_type&lt;br /&gt;
  	&lt;br /&gt;
  	def &amp;lt;(a: Iter, b: Iter): Boolean&lt;br /&gt;
  	def ++(it: Iter): Unit&lt;br /&gt;
  	def *(it: Iter): value_type&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trait VTInputIterator[Iter, VT] extends InputIterator[Iter] {&lt;br /&gt;
	type value_type = VT&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class ArrayListIterator[T](a: ArrayList[T], i: Int) {&lt;br /&gt;
	val arr: ArrayList[T] = a&lt;br /&gt;
	var ind: Int = i&lt;br /&gt;
	&lt;br /&gt;
	def curr(): T = arr.get(ind)&lt;br /&gt;
	def ++(): Unit = { ind += 1 }&lt;br /&gt;
	&lt;br /&gt;
	override def toString() = &amp;quot;[&amp;quot; + ind.toString() + &amp;quot;]&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class InputIterArrList[T] extends VTInputIterator[ArrayListIterator[T], T]{	&lt;br /&gt;
	def &amp;lt;(a: ArrayListIterator[T], b: ArrayListIterator[T]) = {&lt;br /&gt;
	  if (a.arr == b.arr) a.ind &amp;lt; b.ind&lt;br /&gt;
	  else throw new IllegalArgumentException()&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	def ++(it: ArrayListIterator[T]): Unit = it.++()&lt;br /&gt;
	def *(it: ArrayListIterator[T]) = it.curr()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
object TestInputIterator extends Application{	&lt;br /&gt;
  &lt;br /&gt;
	def find[Iter, VT, V](first: Iter, last: Iter, x: V)(implicit iterator: VTInputIterator[Iter, VT], &lt;br /&gt;
	    cmp: EqualityComparable[VT, V]): Iter = &lt;br /&gt;
	{&lt;br /&gt;
	  while (iterator.&amp;lt;(first, last) &amp;amp;&amp;amp; cmp.!=(iterator.*(first), x))&lt;br /&gt;
	    iterator.++(first)&lt;br /&gt;
	  first&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	implicit object EqIntInt extends EqualityComparable[Int, Int] {&lt;br /&gt;
	  def ==(a: Int, b: Int): Boolean = { a == b }&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	implicit object inputIterArrListInt extends InputIterArrList[Int]{}&lt;br /&gt;
	&lt;br /&gt;
	val len = 10;&lt;br /&gt;
	var arr: ArrayList[Int] = new ArrayList(len);&lt;br /&gt;
	for (i: Int &amp;lt;- 1 to len)&lt;br /&gt;
	  arr.add(i)&lt;br /&gt;
	var arrFirst = new ArrayListIterator(arr, 0)&lt;br /&gt;
	var arrLast = new ArrayListIterator(arr, len)&lt;br /&gt;
	var r = find(arrFirst, arrLast, 7)&lt;br /&gt;
	println(r)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Juliet:'''''&lt;br /&gt;
&lt;br /&gt;
В общем, итоги на SO (http://stackoverflow.com/questions/15001138/modelling-of-c-concepts-with-scala-traits).&lt;br /&gt;
&lt;br /&gt;
То есть я так понимаю, на Scala мы пишем примерно то, во что генерируются концепты у Сика. То есть явно передаем модели.&lt;br /&gt;
&lt;br /&gt;
И с другой стороны есть возможность указать надтип и подтип для параметров шаблона.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2594</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2594"/>
		<updated>2013-02-21T10:30:31Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
16 страниц. &lt;br /&gt;
&lt;br /&gt;
Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Раз концепты есть, то как-то можно обеспечить концепт, связывающий два и более параметров шаблона. Как? &lt;br /&gt;
Может, в статье всё-таки ничего не говорится о концептах?&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Слова «концепты» в статье вообще нет, это правда. Есть пример моделирования классов типов Haskell.&lt;br /&gt;
&lt;br /&gt;
А связать несколько параметров можно, просто trait с несколькими параметрами.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
trait myTrait[S, T] {&lt;br /&gt;
  def convert(x: S): T&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Ну, это не очень - это и на C++ старом можно написать. А вот пример использования triats как концептов в новом C++ можно? В стиле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;template&amp;lt;InputIterator Iter, typename V&amp;gt;&lt;br /&gt;
requires EqualityComparable&amp;lt;Iter::value_type, V&amp;gt;&lt;br /&gt;
Iter find(Iter first, Iter last, V v) { &lt;br /&gt;
  while (first &amp;lt; last &amp;amp;&amp;amp; *first != v)&lt;br /&gt;
    ++first;&lt;br /&gt;
  return first;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
По идее можно, но я опять ничего не понимаю, пытаюсь написать...&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
В общем, у меня все печально. С value_type, спрятанным внутрь траита, совсем ничего не получается. Получился какой-то такой ужас:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
  trait EqualityComparable[S, T] {&lt;br /&gt;
  	def ==(s: S, t: T): Boolean&lt;br /&gt;
  	def !=(s: S, t: T): Boolean = !(s == t)&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  implicit object EqIntInt extends EqualityComparable[Int, Int] {&lt;br /&gt;
  	def ==(a: Int, b: Int): Boolean = { a == b }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  trait PInputIterator[value_type] {&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[value_type]): Boolean&lt;br /&gt;
  	def ++(): Unit&lt;br /&gt;
  	def *(): value_type&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  class IntNumber(x: Int) extends PInputIterator[Int]{&lt;br /&gt;
  	var n = x&lt;br /&gt;
  	&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[Int]): Boolean = {&lt;br /&gt;
  		val y = b.asInstanceOf[IntNumber];&lt;br /&gt;
  		n &amp;lt; y.n&lt;br /&gt;
  	}&lt;br /&gt;
  	def ++(): Unit = { n += 1; }&lt;br /&gt;
  	def *(): Int = n&lt;br /&gt;
  	&lt;br /&gt;
  	override def toString(): String = n.toString()&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  def pfind[X, Iter &amp;lt;: PInputIterator[X], V](first: Iter, last: Iter, v: V)&lt;br /&gt;
  		(implicit cmp: EqualityComparable[X, V]): Iter =&lt;br /&gt;
  {&lt;br /&gt;
    	while (first &amp;lt; last &amp;amp;&amp;amp; cmp.!=(first.*(), v))&lt;br /&gt;
    		first.++()&lt;br /&gt;
  	first&lt;br /&gt;
  }                                               //&amp;gt; pfind: [X, Iter &amp;lt;: concepts.iterator.PInputIterator[X], V](first: Iter, las&lt;br /&gt;
                                                  //| t: Iter, v: V)(implicit cmp: concepts.iterator.EqualityComparable[X,V])Iter&lt;br /&gt;
                                                  //| &lt;br /&gt;
  &lt;br /&gt;
  var c5 = new IntNumber(5)                //&amp;gt; c5  : concepts.iterator.IntNumber = 5&lt;br /&gt;
  var c15 = new IntNumber(15)              //&amp;gt; c15  : concepts.iterator.IntNumber = 15&lt;br /&gt;
  val d11 = pfind[Int, IntNumber, Int](c5, c15, 11)&lt;br /&gt;
                                                  //&amp;gt; d11  : concepts.iterator.IntNumber = 11&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причем ''не указывать'' параметры при вызове pfind не получается, ошибка: &amp;lt;tt&amp;gt;Type inferred type arguments [Nothing,IntNumber,Int] do not conform to method pfind's type parameter bounds [X,Iter &amp;lt;: PInputIterator[X],V]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Я снова открыла статью, про которую Артем на семинаре докладывал. Она несколько нивелировала влияние статьи «Generics of a Higher Kind». Теперь у меня вот так получилось (добраться до внутреннего типа все равно никак не получается):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
trait EqualityComparable[S, T] {&lt;br /&gt;
	def ==(s: S, t: T): Boolean&lt;br /&gt;
  	def !=(s: S, t: T): Boolean = !(s == t)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trait InputIterator[Iter] {&lt;br /&gt;
	type value_type&lt;br /&gt;
  	&lt;br /&gt;
  	def &amp;lt;(a: Iter, b: Iter): Boolean&lt;br /&gt;
  	def ++(it: Iter): Unit&lt;br /&gt;
  	def *(it: Iter): value_type&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trait VTInputIterator[Iter, VT] extends InputIterator[Iter] {&lt;br /&gt;
	type value_type = VT&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class ArrayListIterator[T](a: ArrayList[T], i: Int) {&lt;br /&gt;
	val arr: ArrayList[T] = a&lt;br /&gt;
	var ind: Int = i&lt;br /&gt;
	&lt;br /&gt;
	def curr(): T = arr.get(ind)&lt;br /&gt;
	def ++(): Unit = { ind += 1 }&lt;br /&gt;
	&lt;br /&gt;
	override def toString() = &amp;quot;[&amp;quot; + ind.toString() + &amp;quot;]&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class InputIterArrList[T] extends VTInputIterator[ArrayListIterator[T], T]{	&lt;br /&gt;
	def &amp;lt;(a: ArrayListIterator[T], b: ArrayListIterator[T]) = {&lt;br /&gt;
	  if (a.arr == b.arr) a.ind &amp;lt; b.ind&lt;br /&gt;
	  else throw new IllegalArgumentException()&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	def ++(it: ArrayListIterator[T]): Unit = it.++()&lt;br /&gt;
	def *(it: ArrayListIterator[T]) = it.curr()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
object TestInputIterator extends Application{	&lt;br /&gt;
  &lt;br /&gt;
	def find[Iter, VT, V](first: Iter, last: Iter, x: V)(implicit iterator: VTInputIterator[Iter, VT], &lt;br /&gt;
	    cmp: EqualityComparable[VT, V]): Iter = &lt;br /&gt;
	{&lt;br /&gt;
	  while (iterator.&amp;lt;(first, last) &amp;amp;&amp;amp; cmp.!=(iterator.*(first), x))&lt;br /&gt;
	    iterator.++(first)&lt;br /&gt;
	  first&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	implicit object EqIntInt extends EqualityComparable[Int, Int] {&lt;br /&gt;
	  def ==(a: Int, b: Int): Boolean = { a == b }&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	implicit object inputIterArrListInt extends InputIterArrList[Int]{}&lt;br /&gt;
	&lt;br /&gt;
	val len = 10;&lt;br /&gt;
	var arr: ArrayList[Int] = new ArrayList(len);&lt;br /&gt;
	for (i: Int &amp;lt;- 1 to len)&lt;br /&gt;
	  arr.add(i)&lt;br /&gt;
	var arrFirst = new ArrayListIterator(arr, 0)&lt;br /&gt;
	var arrLast = new ArrayListIterator(arr, len)&lt;br /&gt;
	var r = find(arrFirst, arrLast, 7)&lt;br /&gt;
	println(r)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2593</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2593"/>
		<updated>2013-02-20T19:28:05Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
16 страниц. &lt;br /&gt;
&lt;br /&gt;
Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Раз концепты есть, то как-то можно обеспечить концепт, связывающий два и более параметров шаблона. Как? &lt;br /&gt;
Может, в статье всё-таки ничего не говорится о концептах?&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Слова «концепты» в статье вообще нет, это правда. Есть пример моделирования классов типов Haskell.&lt;br /&gt;
&lt;br /&gt;
А связать несколько параметров можно, просто trait с несколькими параметрами.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
trait myTrait[S, T] {&lt;br /&gt;
  def convert(x: S): T&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Ну, это не очень - это и на C++ старом можно написать. А вот пример использования triats как концептов в новом C++ можно? В стиле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;template&amp;lt;InputIterator Iter, typename V&amp;gt;&lt;br /&gt;
requires EqualityComparable&amp;lt;Iter::value_type, V&amp;gt;&lt;br /&gt;
Iter find(Iter first, Iter last, V v) { &lt;br /&gt;
  while (first &amp;lt; last &amp;amp;&amp;amp; *first != v)&lt;br /&gt;
    ++first;&lt;br /&gt;
  return first;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
По идее можно, но я опять ничего не понимаю, пытаюсь написать...&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
В общем, у меня все печально. С value_type, спрятанным внутрь траита, совсем ничего не получается. Получился какой-то такой ужас:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
  trait EqualityComparable[S, T] {&lt;br /&gt;
  	def ==(s: S, t: T): Boolean&lt;br /&gt;
  	def !=(s: S, t: T): Boolean = !(s == t)&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  implicit object EqIntInt extends EqualityComparable[Int, Int] {&lt;br /&gt;
  	def ==(a: Int, b: Int): Boolean = { a == b }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  trait PInputIterator[value_type] {&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[value_type]): Boolean&lt;br /&gt;
  	def ++(): Unit&lt;br /&gt;
  	def *(): value_type&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  class IntNumber(x: Int) extends PInputIterator[Int]{&lt;br /&gt;
  	var n = x&lt;br /&gt;
  	&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[Int]): Boolean = {&lt;br /&gt;
  		val y = b.asInstanceOf[IntNumber];&lt;br /&gt;
  		n &amp;lt; y.n&lt;br /&gt;
  	}&lt;br /&gt;
  	def ++(): Unit = { n += 1; }&lt;br /&gt;
  	def *(): Int = n&lt;br /&gt;
  	&lt;br /&gt;
  	override def toString(): String = n.toString()&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  def pfind[X, Iter &amp;lt;: PInputIterator[X], V](first: Iter, last: Iter, v: V)&lt;br /&gt;
  		(implicit cmp: EqualityComparable[X, V]): Iter =&lt;br /&gt;
  {&lt;br /&gt;
    	while (first &amp;lt; last &amp;amp;&amp;amp; cmp.!=(first.*(), v))&lt;br /&gt;
    		first.++()&lt;br /&gt;
  	first&lt;br /&gt;
  }                                               //&amp;gt; pfind: [X, Iter &amp;lt;: concepts.iterator.PInputIterator[X], V](first: Iter, las&lt;br /&gt;
                                                  //| t: Iter, v: V)(implicit cmp: concepts.iterator.EqualityComparable[X,V])Iter&lt;br /&gt;
                                                  //| &lt;br /&gt;
  &lt;br /&gt;
  var c5 = new IntNumber(5)                //&amp;gt; c5  : concepts.iterator.IntNumber = 5&lt;br /&gt;
  var c15 = new IntNumber(15)              //&amp;gt; c15  : concepts.iterator.IntNumber = 15&lt;br /&gt;
  val d11 = pfind[Int, IntNumber, Int](c5, c15, 11)&lt;br /&gt;
                                                  //&amp;gt; d11  : concepts.iterator.IntNumber = 11&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причем ''не указывать'' параметры при вызове pfind не получается, ошибка: &amp;lt;tt&amp;gt;Type inferred type arguments [Nothing,IntNumber,Int] do not conform to method pfind's type parameter bounds [X,Iter &amp;lt;: PInputIterator[X],V]&amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2592</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2592"/>
		<updated>2013-02-20T19:21:28Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
16 страниц. &lt;br /&gt;
&lt;br /&gt;
Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Раз концепты есть, то как-то можно обеспечить концепт, связывающий два и более параметров шаблона. Как? &lt;br /&gt;
Может, в статье всё-таки ничего не говорится о концептах?&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Слова «концепты» в статье вообще нет, это правда. Есть пример моделирования классов типов Haskell.&lt;br /&gt;
&lt;br /&gt;
А связать несколько параметров можно, просто trait с несколькими параметрами.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
trait myTrait[S, T] {&lt;br /&gt;
  def convert(x: S): T&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Ну, это не очень - это и на C++ старом можно написать. А вот пример использования triats как концептов в новом C++ можно? В стиле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;template&amp;lt;InputIterator Iter, typename V&amp;gt;&lt;br /&gt;
requires EqualityComparable&amp;lt;Iter::value_type, V&amp;gt;&lt;br /&gt;
Iter find(Iter first, Iter last, V v) { &lt;br /&gt;
  while (first &amp;lt; last &amp;amp;&amp;amp; *first != v)&lt;br /&gt;
    ++first;&lt;br /&gt;
  return first;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
По идее можно, но я опять ничего не понимаю, пытаюсь написать...&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
В общем, у меня все печально. С value_type, спрятанным внутрь траита, совсем ничего не получается. Получился какой-то такой ужас:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
  trait EqualityComparable[S, T] {&lt;br /&gt;
  	def ==(s: S, t: T): Boolean&lt;br /&gt;
  	def !=(s: S, t: T): Boolean = !(s == t)&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  implicit object EqIntInt extends EqualityComparable[Int, Int] {&lt;br /&gt;
  	def ==(a: Int, b: Int): Boolean = { a == b }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  trait PInputIterator[value_type] {&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[value_type]): Boolean&lt;br /&gt;
  	def ++(): Unit&lt;br /&gt;
  	def *(): value_type&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  class PIntNumber(x: Int) extends PInputIterator[Int]{&lt;br /&gt;
  	var n = x&lt;br /&gt;
  	&lt;br /&gt;
  	def &amp;lt;(b: PInputIterator[Int]): Boolean = {&lt;br /&gt;
  		val y = b.asInstanceOf[PIntNumber];&lt;br /&gt;
  		n &amp;lt; y.n&lt;br /&gt;
  	}&lt;br /&gt;
  	def ++(): Unit = { n += 1; }&lt;br /&gt;
  	def *(): Int = n&lt;br /&gt;
  	&lt;br /&gt;
  	override def toString(): String = n.toString()&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  def pfind[X, Iter &amp;lt;: PInputIterator[X], V](first: Iter, last: Iter, v: V)&lt;br /&gt;
  		(implicit cmp: EqualityComparable[X, V]): Iter =&lt;br /&gt;
  {&lt;br /&gt;
    	while (first &amp;lt; last &amp;amp;&amp;amp; cmp.!=(first.*(), v))&lt;br /&gt;
    		first.++()&lt;br /&gt;
  	first&lt;br /&gt;
  }                                               //&amp;gt; pfind: [X, Iter &amp;lt;: concepts.iterator.PInputIterator[X], V](first: Iter, las&lt;br /&gt;
                                                  //| t: Iter, v: V)(implicit cmp: concepts.iterator.EqualityComparable[X,V])Iter&lt;br /&gt;
                                                  //| &lt;br /&gt;
  &lt;br /&gt;
  var c5 = new PIntNumber(5)                //&amp;gt; c5  : concepts.iterator.PIntNumber = 5&lt;br /&gt;
  var c15 = new PIntNumber(15)              //&amp;gt; c15  : concepts.iterator.PIntNumber = 15&lt;br /&gt;
  val d11 = pfind[Int, PIntNumber, Int](c5, c15, 11)&lt;br /&gt;
                                                  //&amp;gt; d11  : concepts.iterator.PIntNumber = 11&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причем ''не указывать'' параметры при вызове pfind не получается, ошибка: &amp;lt;tt&amp;gt;Type inferred type arguments [Nothing,PIntNumber,Int] do not conform to method pfind's type parameter bounds [X,Iter &amp;lt;: PInputIterator[X],V]&amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2591</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2591"/>
		<updated>2013-02-18T04:02:41Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
16 страниц. &lt;br /&gt;
&lt;br /&gt;
Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Раз концепты есть, то как-то можно обеспечить концепт, связывающий два и более параметров шаблона. Как? &lt;br /&gt;
Может, в статье всё-таки ничего не говорится о концептах?&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Слова «концепты» в статье вообще нет, это правда. Есть пример моделирования классов типов Haskell.&lt;br /&gt;
&lt;br /&gt;
А связать несколько параметров можно, просто trait с несколькими параметрами.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
trait myTrait[S, T] {&lt;br /&gt;
  def convert(x: S): T&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Ну, это не очень - это и на C++ старом можно написать. А вот пример использования triats как концептов в новом C++ можно? В стиле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;template&amp;lt;InputIterator Iter, typename V&amp;gt;&lt;br /&gt;
requires EqualityComparable&amp;lt;Iter::value_type, V&amp;gt;&lt;br /&gt;
Iter find(Iter first, Iter last, V v) { &lt;br /&gt;
  while (first &amp;lt; last &amp;amp;&amp;amp; *first != v)&lt;br /&gt;
    ++first;&lt;br /&gt;
  return first;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
По идее можно, но я опять ничего не понимаю, пытаюсь написать...&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2589</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2589"/>
		<updated>2013-01-31T19:23:11Z</updated>

		<summary type="html">&lt;p&gt;Juliet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
16 страниц. &lt;br /&gt;
&lt;br /&gt;
Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;br /&gt;
&lt;br /&gt;
'''''Miks''':''&lt;br /&gt;
&lt;br /&gt;
Раз концепты есть, то как-то можно обеспечить концепт, связывающий два и более параметров шаблона. Как? &lt;br /&gt;
Может, в статье всё-таки ничего не говорится о концептах?&lt;br /&gt;
&lt;br /&gt;
'''''Juliet''':''&lt;br /&gt;
&lt;br /&gt;
Слова «концепты» в статье вообще нет, это правда. Есть пример моделирования классов типов Haskell.&lt;br /&gt;
&lt;br /&gt;
А связать несколько параметров можно, просто trait с несколькими параметрами.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
trait myTrait[S, T] {&lt;br /&gt;
  def convert(x: S): T&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2586</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2586"/>
		<updated>2013-01-31T19:03:43Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
16 страниц. &lt;br /&gt;
&lt;br /&gt;
Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2585</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2585"/>
		<updated>2013-01-31T18:56:43Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
16 страниц. Название обещает дженерики высшего сорта!&lt;br /&gt;
&lt;br /&gt;
Во-первых, надо признаться, что у меня разрыв шаблона. Когда я смотрю на Scala-код в статье, я совершенно перестаю понимать, где здесь концепты, а где классы. Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Кажется, в процессе написания отчета я начинаю что-то понимать...'' На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по-нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривать не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2584</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2584"/>
		<updated>2013-01-31T18:51:40Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
16 страниц. Название обещает дженерики высшего сорта!&lt;br /&gt;
&lt;br /&gt;
Во-первых, надо признаться, что у меня разрыв шаблона. Когда я смотрю на Scala-код в статье, я совершенно перестаю понимать, где здесь концепты, а где классы. Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Кажется, в процессе написания отчета я начинаю что-то понимать...'' На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть по нашему — если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;br /&gt;
&lt;br /&gt;
Еще один интересный момент, рассматривающийся в статье — сорта типов. Из Haskell мы помним (про расширения я ничего не знаю, к сожалению), что конкретный тип имеет сорт «*», конструктор с одним параметром — «* → *», и так далее. Здесь предлагается рассматривается не просто «*», а «*(lowerBound, upperBound)». То есть сорт содержит информацию об ограничениях типовых составляющих.&lt;br /&gt;
&lt;br /&gt;
Далее говорится о том, что на сортах можно ввести отношение «подсортирования». И еще есть раздел с красивым названием «kind soundness».&lt;br /&gt;
&lt;br /&gt;
В общем, по-моему это крутая статья. Надо над ней подумать...&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2583</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2583"/>
		<updated>2013-01-31T18:42:08Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
16 страниц. Название обещает дженерики высшего сорта!&lt;br /&gt;
&lt;br /&gt;
Во-первых, надо признаться, что у меня разрыв шаблона. Когда я смотрю на Scala-код в статье, я совершенно перестаю понимать, где здесь концепты, а где классы. Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Кажется, в процессе написания отчета я начинаю что-то понимать...'' На параметры шаблона можно наложить только два вида ограничений: надтипа и подтипа. Соответственно, если хочется получить несколько разносортных ограничений (то есть если мы хотим, чтобы тип удовлетворял нескольким концептам), надо сделать trait-наследник всех интересующих нас концептов и указать его в качестве надтипа.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2582</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2582"/>
		<updated>2013-01-31T18:34:49Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Generics of a Higher Kind */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
16 страниц. Название обещает дженерики высшего сорта!&lt;br /&gt;
&lt;br /&gt;
Во-первых, надо признаться, что у меня разрыв шаблона. Когда я смотрю на Scala-код в статье, я совершенно перестаю понимать, где здесь концепты, а где классы. Насколько я понимаю, концептов в том смысле, как мы уже привыкли их воспринимать, здесь нет. Сплошные классы.&lt;br /&gt;
&lt;br /&gt;
Точнее, есть '''trait''' и '''class'''. Из статьи: класс может наследоваться от другого класса и нескольких траитов. Траит это класс, который может комбинироваться с другими траитами с помощью некой ограниченной версии множественного наследования.&lt;br /&gt;
&lt;br /&gt;
Далее говорится, что в статье разница между траитами и классами не так важна, так что все называется классами.&lt;br /&gt;
&lt;br /&gt;
Класс может быть параметризован. А может содержать абстрактный тип-член. И они вроде бы ничем по сути не отличаются кроме области видимости.&lt;br /&gt;
&lt;br /&gt;
Соль типов-параметров шаблона в том, что в качестве параметра может быть не конкретный тип, а '''конструктор типа'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait Iterable[T, Container[X]] {&lt;br /&gt;
  def filter(p: T =&amp;gt; Boolean): Container[T]&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это означает, что первый параметр — конкретный тип, а второй параметр — конструктор типа от одного параметра. И далее можем написать так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Scala&amp;quot;&amp;gt;&lt;br /&gt;
trait List[T] extends Iterable[T, List]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2581</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2581"/>
		<updated>2013-01-31T17:52:06Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Краткий отчет о статьях */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;br /&gt;
&lt;br /&gt;
==== Generics of a Higher Kind ==== &lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
16 страниц. Дженерики высшего сорта, чистая правда!&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2580</id>
		<title>Страничка семинара теории типов</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BA%D0%B0_%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%B0_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2&amp;diff=2580"/>
		<updated>2013-01-31T17:50:33Z</updated>

		<summary type="html">&lt;p&gt;Juliet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;По концептам, типам следует читать современные статьи&lt;br /&gt;
&lt;br /&gt;
Можно начинать со школы Одерского:&lt;br /&gt;
&lt;br /&gt;
[http://www.scala-lang.org/node/143 Статьи по теоретическим основам языка Скала]&lt;br /&gt;
&lt;br /&gt;
Выделю тут ряд статей, с которых, по моему мнению, следует начинать:&lt;br /&gt;
&lt;br /&gt;
* [http://drops.dagstuhl.de/opus/volltexte/2009/2338/pdf/09005.OderskyM.2338.pdf Fighting Bit Rot with Types (Experience Report: Scala Collections)]&lt;br /&gt;
* [http://lamp.epfl.ch/~dragos/files/scala-spec.pdf Compiling Generics Through User-Directed Type Specialization]&lt;br /&gt;
* [http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf Implementing First-Class Polymorphic Delimited Continuations by a Type-Directed Selective CPS-Transform]&lt;br /&gt;
* [http://www.comlab.ox.ac.uk//files/2187/ModularVisitor.pdf Modular Visitor Components: A Practical Solution to the Expression Families Problem]&lt;br /&gt;
* [http://adriaanm.github.com/files/higher.pdf Generics of a Higher Kind]&lt;br /&gt;
* [http://adriaanm.github.com/files/scalina-final.pdf Safe Type-level Abstraction in Scala]&lt;br /&gt;
* [http://infoscience.epfl.ch/getfile.py?docid=13847&amp;amp;name=TranslationCorrectness-TR&amp;amp;format=pdf&amp;amp;version=1 Translation Correctness for First-Order Object-Oriented Pattern Matching]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/mfcs06.pdf A Core Calculus for Scala Type Checking]&lt;br /&gt;
* [http://www.scala-lang.org/sites/default/files/odersky/ecoop03.pdf A Nominal Theory of Objects with Dependent Types]&lt;br /&gt;
&lt;br /&gt;
== Краткий отчет о статьях ==&lt;br /&gt;
==== Compiling Generics Through User-Directed Type Specialization ====&lt;br /&gt;
''Juliet:''&lt;br /&gt;
&lt;br /&gt;
Небольшая статья, 6 страниц. О технических особенностях генерации кода для шаблонов. &lt;br /&gt;
&lt;br /&gt;
В двух словах речь о том, что использовать код, который генерируется для шаблона после стирания типов (где вместо типа &amp;lt;tt&amp;gt;T&amp;lt;/tt&amp;gt; возникает &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;) неэффективно для примитивных типов. Так как их приходится заворачивать в классы-обертки, и, соответственно, в специализированной версии возникают лишние операции boxing/unboxing.&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативы при описании шаблона для типа-параметра шаблона можно указать ключевое слово '''specialized''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;scala&amp;quot;&amp;gt;&lt;br /&gt;
def someFun[@specialized T](...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В этом случае помимо кода с &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt; будут сгенерированы специализации для примитивных типов.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Juliet&amp;diff=2553</id>
		<title>Участник:Juliet</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Juliet&amp;diff=2553"/>
		<updated>2012-09-02T09:08:44Z</updated>

		<summary type="html">&lt;p&gt;Juliet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Юлия Белякова.&amp;lt;br /&amp;gt;&lt;br /&gt;
Мехмат ЮФУ (РГУ)&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A7%D0%B0%D1%81%D1%82%D0%BE_%D0%B7%D0%B0%D0%B4%D0%B0%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BF%D0%BE_WDE&amp;diff=2248</id>
		<title>Часто задаваемые вопросы по WDE</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A7%D0%B0%D1%81%D1%82%D0%BE_%D0%B7%D0%B0%D0%B4%D0%B0%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BF%D0%BE_WDE&amp;diff=2248"/>
		<updated>2011-12-09T12:21:38Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Что такое интерфейс учебных курсов? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Для чего нужна WDE ===&lt;br /&gt;
Предполагается, что среда WDE будет активно использоваться в обучении: для публикации учебных программ, для выполнения программ без установленного компилятора, для ссылок на программы с различных форумов и сайтов.&lt;br /&gt;
&lt;br /&gt;
Все сценарии использования WDE пока не изучены - их будут предлагать наши пользователи.&lt;br /&gt;
&lt;br /&gt;
=== Что такое PascalABC.NET ===&lt;br /&gt;
PascalABC.NET - это современный язык Паскаль, разработанный на [http://mmcs.sfedu.ru/ факультете математики, механики и компьютерных наук Южного Федерального университета]. Он полностью совместим с Delphi Object Pascal и Borland (Turbo) Pascal. Он имеет также ряд расширений и как .NET-язык может свободно пользоваться всеми .NET-библиотеками.&lt;br /&gt;
&lt;br /&gt;
PascalABC.NET широко используется в обучении. Он позволяет программировать как на базовом Паскале, так и использовать объектно-ориентированные возможности.&lt;br /&gt;
&lt;br /&gt;
Более детально ознакомиться с PascalABC.NET можно на [http://pascalabc.net/ сайте проекта].&lt;br /&gt;
&lt;br /&gt;
=== Как опубликовать файл и дать ссылку на опубликованный файл ===&lt;br /&gt;
Достаточно нажать кнопку Опубликовать. Файл будет опубликован на сервере WDE в специальном каталоге. Файл при этом должен содержать правильную PascalABC.NET-программу.&lt;br /&gt;
&lt;br /&gt;
После публикации важно сразу сохранить у себя ссылку на опубликованный файл - она хранится только во время сеанса пользователя, т.е. до закрытия браузера. &lt;br /&gt;
&lt;br /&gt;
Зная имя опубликованного файла, его можно открыть в WDE, нажав кнопку Открыть опубликованный файл, а также опубликовать ссылку на него на другом сайте или форуме в виде http://pascalabc.net/WDE/?file=имя_файла.pas&lt;br /&gt;
&lt;br /&gt;
=== В течение какого времени на сервере хранятся опубликованные файлы ===&lt;br /&gt;
Несколько месяцев. Для зарегистрированных пользователей время хранения файлов на сервере больше.&lt;br /&gt;
&lt;br /&gt;
=== Насколько быстро выполняется программа ===&lt;br /&gt;
О, поверьте - очень быстро! Программа выполняется на сервере, сервер - мощный, куплен в рамках национального проекта &amp;quot;Образование&amp;quot; :)&lt;br /&gt;
Потому и быстро.&lt;br /&gt;
&lt;br /&gt;
Для примера: &lt;br /&gt;
[http://pascalabc.net/WDE/?file=Speed1.pas вот эта программа] иллюстрирует скорость вычислений.&lt;br /&gt;
Аналогичная программа, написанная на Delphi, работает процентов на 15 дольше. Попробуйте!&lt;br /&gt;
&lt;br /&gt;
=== Можно ли использовать модули (библиотеки) ===&lt;br /&gt;
Можно, но неудобно. По крайней мере, пока. Причина: модули приходится всякий раз создавать вручную во время сеанса и сохранять в каталоге сеанса пользователя под именем, совпадающим с именем модуля. Аналогичное можно сказать про dll библиотеки.&lt;br /&gt;
&lt;br /&gt;
А вот зарегистрированные пользователи работают каждый в своем каталоге, и проблем с сохранением модулей и библиотек нет.&lt;br /&gt;
&lt;br /&gt;
=== Для чего нужна регистрация ===&lt;br /&gt;
Зарегистрированные пользователи получают в свое полное распоряжение целый каталог на сервере, который не удаляется после завершения сеанса.&lt;br /&gt;
Кроме того, для них открывается ряд новых возможностей:&lt;br /&gt;
* переименование и удаление файлов&lt;br /&gt;
* создание каталогов и подкаталогов&lt;br /&gt;
* переименование и удаление каталогов&lt;br /&gt;
* длительное хранение опубликованных файлов&lt;br /&gt;
* открытие публичного доступа к своим файлам на чтение&lt;br /&gt;
* '''использование интерфейса учебных курсов'''&lt;br /&gt;
&lt;br /&gt;
=== Что такое интерфейс учебных курсов? ===&lt;br /&gt;
Появилась возможность упростить использование веб-среды для обучения. Теперь ''зарегистрированные'' пользователи могут получать роли ''преподавателей'' и ''учеников''.&lt;br /&gt;
&lt;br /&gt;
''Преподаватели'' могут создавать учебные курсы и записывать на них учеников (для этого нужно знать логин ученика). Ученики могут и сами записываться на курсы. Сделать это можно [http://pascalabc.net/WDE/LearnCourses.aspx здесь]. &lt;br /&gt;
&lt;br /&gt;
Что такое '''учебный курс'''? Это возможность разделить ''личные'' и ''учебные'' файлы пользователей, а также значительно упростить проверку заданий для преподавателя. Для преподавателей и учеников к привычному списку файлов пользователя добавляется учебный раздел. В нем располагаются папки учебных курсов.  &amp;lt;br /&amp;gt;&lt;br /&gt;
Для преподавателя эта папка выглядит так:&lt;br /&gt;
 - файлы курса&lt;br /&gt;
 - ученик1&lt;br /&gt;
 - ученик2&lt;br /&gt;
  ...&lt;br /&gt;
 - ученикN&lt;br /&gt;
В ''файлах курса'' преподаватель может размещать файлы, которые будут доступны на чтение всем ученикам. Например, файлы примеров или некоторые заготовки.&lt;br /&gt;
&lt;br /&gt;
Для ученика каталог учебного курса содержит&lt;br /&gt;
 - файлы курса&lt;br /&gt;
 - мои файлы&lt;br /&gt;
Файлы курса доступны только на чтение. ''Мои файлы'' будут доступны не только ученику, но и преподавателю.&lt;br /&gt;
&lt;br /&gt;
=== Я хочу получить роль преподавателя. Что нужно сделать? ===&lt;br /&gt;
Нужно [mailto://miks@math.rsu.ru написать письмо] разработчикам  с просьбой выдать Вам права преподавателя.&lt;br /&gt;
&lt;br /&gt;
=== Я хочу получить роль ученика. Что нужно сделать? ===&lt;br /&gt;
Роль ученика скорее всего нужна Вам для участия в учебном курсе. Просто перейдите на [http://pascalabc.net/WDE/LearnCourses.aspx страницу курса] и запишитесь на нужный курс (возле каждого курса справа Вы найдете кнопку ''«записаться»''). Обратите внимание, что для записи на курс сначала нужно авторизоваться в веб-среде.&lt;br /&gt;
&lt;br /&gt;
=== У меня есть роль преподавателя. Как создать курс? ===&lt;br /&gt;
Авторизуйтесь в веб-среде и перейдите на [http://pascalabc.net/WDE/LearnCourses.aspx страницу курса]. Там Вы найдете кнопку ''«создать новый курс»''. Необходимо будет заполнить краткую информацию о курсе. Там же можно добавить на курс учеников (ученики могут записаться на курс и самостоятельно). После создания курса Вы всегда сможете его отредактировать. &amp;lt;br /&amp;gt;&lt;br /&gt;
Обратите внимание, что курс могут «вести» и несколько преподавателей. Чтобы добавить преподавателя к Вашему курсу, нужно будет [mailto://miks@math.rsu.ru написать письмо] разработчикам.&lt;br /&gt;
&lt;br /&gt;
=== Среда «зависла». Что делать?! ===&lt;br /&gt;
Скорее всего, произошел сбой сети или немного устал сервер. Например, Вы запустили компиляцию, а результата все нет и нет. &amp;lt;br /&amp;gt;&lt;br /&gt;
Найдите в меню редактора кнопочку &amp;lt;tt&amp;gt;«Прервать запросы на сервер»&amp;lt;/tt&amp;gt; и нажмите её. Это должно помочь. После этого повторите операцию еще раз. Если у Вас постоянные проблемы с сетью, то, возможно, придется использовать эту кнопку часто.&lt;br /&gt;
&lt;br /&gt;
Крайняя мера восстановления работоспособности среды — обновление страницы в браузере.&lt;br /&gt;
&lt;br /&gt;
=== Могу ли я работать с WDE без подключения к Интернету ===&lt;br /&gt;
Нет. Но чтобы запускать те же программы, что и в WDE, вы можете скачать и установить [http://pascalabc.net/ru/ssyilki-dlya-skachivaniya.html систему программирования PascalABC.NET] и работать в ней локально без подключения к Интернету.&lt;br /&gt;
&lt;br /&gt;
=== Я нашел ошибку! Куда писать? ===&lt;br /&gt;
Открываем вот эту страничку разработчиков:&lt;br /&gt;
http://pascalabc.net/razrabotchiki-pascalabc-net&lt;br /&gt;
И находим первый адрес.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A7%D0%B0%D1%81%D1%82%D0%BE_%D0%B7%D0%B0%D0%B4%D0%B0%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BF%D0%BE_WDE&amp;diff=2247</id>
		<title>Часто задаваемые вопросы по WDE</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A7%D0%B0%D1%81%D1%82%D0%BE_%D0%B7%D0%B0%D0%B4%D0%B0%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BF%D0%BE_WDE&amp;diff=2247"/>
		<updated>2011-12-09T06:44:27Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Для чего нужна регистрация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Для чего нужна WDE ===&lt;br /&gt;
Предполагается, что среда WDE будет активно использоваться в обучении: для публикации учебных программ, для выполнения программ без установленного компилятора, для ссылок на программы с различных форумов и сайтов.&lt;br /&gt;
&lt;br /&gt;
Все сценарии использования WDE пока не изучены - их будут предлагать наши пользователи.&lt;br /&gt;
&lt;br /&gt;
=== Что такое PascalABC.NET ===&lt;br /&gt;
PascalABC.NET - это современный язык Паскаль, разработанный на [http://mmcs.sfedu.ru/ факультете математики, механики и компьютерных наук Южного Федерального университета]. Он полностью совместим с Delphi Object Pascal и Borland (Turbo) Pascal. Он имеет также ряд расширений и как .NET-язык может свободно пользоваться всеми .NET-библиотеками.&lt;br /&gt;
&lt;br /&gt;
PascalABC.NET широко используется в обучении. Он позволяет программировать как на базовом Паскале, так и использовать объектно-ориентированные возможности.&lt;br /&gt;
&lt;br /&gt;
Более детально ознакомиться с PascalABC.NET можно на [http://pascalabc.net/ сайте проекта].&lt;br /&gt;
&lt;br /&gt;
=== Как опубликовать файл и дать ссылку на опубликованный файл ===&lt;br /&gt;
Достаточно нажать кнопку Опубликовать. Файл будет опубликован на сервере WDE в специальном каталоге. Файл при этом должен содержать правильную PascalABC.NET-программу.&lt;br /&gt;
&lt;br /&gt;
После публикации важно сразу сохранить у себя ссылку на опубликованный файл - она хранится только во время сеанса пользователя, т.е. до закрытия браузера. &lt;br /&gt;
&lt;br /&gt;
Зная имя опубликованного файла, его можно открыть в WDE, нажав кнопку Открыть опубликованный файл, а также опубликовать ссылку на него на другом сайте или форуме в виде http://pascalabc.net/WDE/?file=имя_файла.pas&lt;br /&gt;
&lt;br /&gt;
=== В течение какого времени на сервере хранятся опубликованные файлы ===&lt;br /&gt;
Несколько месяцев. Для зарегистрированных пользователей время хранения файлов на сервере больше.&lt;br /&gt;
&lt;br /&gt;
=== Насколько быстро выполняется программа ===&lt;br /&gt;
О, поверьте - очень быстро! Программа выполняется на сервере, сервер - мощный, куплен в рамках национального проекта &amp;quot;Образование&amp;quot; :)&lt;br /&gt;
Потому и быстро.&lt;br /&gt;
&lt;br /&gt;
Для примера: &lt;br /&gt;
[http://pascalabc.net/WDE/?file=Speed1.pas вот эта программа] иллюстрирует скорость вычислений.&lt;br /&gt;
Аналогичная программа, написанная на Delphi, работает процентов на 15 дольше. Попробуйте!&lt;br /&gt;
&lt;br /&gt;
=== Можно ли использовать модули (библиотеки) ===&lt;br /&gt;
Можно, но неудобно. По крайней мере, пока. Причина: модули приходится всякий раз создавать вручную во время сеанса и сохранять в каталоге сеанса пользователя под именем, совпадающим с именем модуля. Аналогичное можно сказать про dll библиотеки.&lt;br /&gt;
&lt;br /&gt;
А вот зарегистрированные пользователи работают каждый в своем каталоге, и проблем с сохранением модулей и библиотек нет.&lt;br /&gt;
&lt;br /&gt;
=== Для чего нужна регистрация ===&lt;br /&gt;
Зарегистрированные пользователи получают в свое полное распоряжение целый каталог на сервере, который не удаляется после завершения сеанса.&lt;br /&gt;
Кроме того, для них открывается ряд новых возможностей:&lt;br /&gt;
* переименование и удаление файлов&lt;br /&gt;
* создание каталогов и подкаталогов&lt;br /&gt;
* переименование и удаление каталогов&lt;br /&gt;
* длительное хранение опубликованных файлов&lt;br /&gt;
* открытие публичного доступа к своим файлам на чтение&lt;br /&gt;
* '''использование интерфейса учебных курсов'''&lt;br /&gt;
&lt;br /&gt;
=== Что такое интерфейс учебных курсов? ===&lt;br /&gt;
Появилась возможность упростить использование веб-среды для обучения. Теперь пользователи могут получать роли ''преподавателей'' и ''учеников''.&lt;br /&gt;
&lt;br /&gt;
''Преподаватели'' могут создавать учебные курсы и записывать на них учеников (для этого нужно знать логин ученика). Ученики могут и сами записываться на курсы. Сделать это можно [http://pascalabc.net/WDE/LearnCourses.aspx здесь]. &lt;br /&gt;
&lt;br /&gt;
Что такое '''учебный курс'''? Это возможность разделить ''личные'' и ''учебные'' файлы пользователей, а также значительно упростить проверку заданий для преподавателя. Для преподавателей и учеников к привычному списку файлов пользователя добавляется учебный раздел. В нем располагаются папки учебных курсов.  &amp;lt;br /&amp;gt;&lt;br /&gt;
Для преподавателя эта папка выглядит так:&lt;br /&gt;
 - файлы курса&lt;br /&gt;
 - ученик1&lt;br /&gt;
 - ученик2&lt;br /&gt;
  ...&lt;br /&gt;
 - ученикN&lt;br /&gt;
В ''файлах курса'' преподаватель может размещать файлы, которые будут доступны на чтение всем ученикам. Например, файлы примеров или некоторые заготовки.&lt;br /&gt;
&lt;br /&gt;
Для ученика каталог учебного курса содержит&lt;br /&gt;
 - файлы курса&lt;br /&gt;
 - мои файлы&lt;br /&gt;
Файлы курса доступны только на чтение. ''Мои файлы'' будут доступны не только ученику, но и преподавателю.&lt;br /&gt;
&lt;br /&gt;
=== Среда «зависла». Что делать?! ===&lt;br /&gt;
Скорее всего, произошел сбой сети или немного устал сервер. Например, Вы запустили компиляцию, а результата все нет и нет. &amp;lt;br /&amp;gt;&lt;br /&gt;
Найдите в меню редактора кнопочку &amp;lt;tt&amp;gt;«Прервать запросы на сервер»&amp;lt;/tt&amp;gt; и нажмите её. Это должно помочь. После этого повторите операцию еще раз. Если у Вас постоянные проблемы с сетью, то, возможно, придется использовать эту кнопку часто.&lt;br /&gt;
&lt;br /&gt;
Крайняя мера восстановления работоспособности среды — обновление страницы в браузере.&lt;br /&gt;
&lt;br /&gt;
=== Могу ли я работать с WDE без подключения к Интернету ===&lt;br /&gt;
Нет. Но чтобы запускать те же программы, что и в WDE, вы можете скачать и установить [http://pascalabc.net/ru/ssyilki-dlya-skachivaniya.html систему программирования PascalABC.NET] и работать в ней локально без подключения к Интернету.&lt;br /&gt;
&lt;br /&gt;
=== Я нашел ошибку! Куда писать? ===&lt;br /&gt;
Открываем вот эту страничку разработчиков:&lt;br /&gt;
http://pascalabc.net/razrabotchiki-pascalabc-net&lt;br /&gt;
И находим первый адрес.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%A7%D0%B0%D1%81%D1%82%D0%BE_%D0%B7%D0%B0%D0%B4%D0%B0%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BF%D0%BE_WDE&amp;diff=2246</id>
		<title>Часто задаваемые вопросы по WDE</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%A7%D0%B0%D1%81%D1%82%D0%BE_%D0%B7%D0%B0%D0%B4%D0%B0%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BF%D0%BE_WDE&amp;diff=2246"/>
		<updated>2011-12-09T06:29:27Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Для чего нужна регистрация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Для чего нужна WDE ===&lt;br /&gt;
Предполагается, что среда WDE будет активно использоваться в обучении: для публикации учебных программ, для выполнения программ без установленного компилятора, для ссылок на программы с различных форумов и сайтов.&lt;br /&gt;
&lt;br /&gt;
Все сценарии использования WDE пока не изучены - их будут предлагать наши пользователи.&lt;br /&gt;
&lt;br /&gt;
=== Что такое PascalABC.NET ===&lt;br /&gt;
PascalABC.NET - это современный язык Паскаль, разработанный на [http://mmcs.sfedu.ru/ факультете математики, механики и компьютерных наук Южного Федерального университета]. Он полностью совместим с Delphi Object Pascal и Borland (Turbo) Pascal. Он имеет также ряд расширений и как .NET-язык может свободно пользоваться всеми .NET-библиотеками.&lt;br /&gt;
&lt;br /&gt;
PascalABC.NET широко используется в обучении. Он позволяет программировать как на базовом Паскале, так и использовать объектно-ориентированные возможности.&lt;br /&gt;
&lt;br /&gt;
Более детально ознакомиться с PascalABC.NET можно на [http://pascalabc.net/ сайте проекта].&lt;br /&gt;
&lt;br /&gt;
=== Как опубликовать файл и дать ссылку на опубликованный файл ===&lt;br /&gt;
Достаточно нажать кнопку Опубликовать. Файл будет опубликован на сервере WDE в специальном каталоге. Файл при этом должен содержать правильную PascalABC.NET-программу.&lt;br /&gt;
&lt;br /&gt;
После публикации важно сразу сохранить у себя ссылку на опубликованный файл - она хранится только во время сеанса пользователя, т.е. до закрытия браузера. &lt;br /&gt;
&lt;br /&gt;
Зная имя опубликованного файла, его можно открыть в WDE, нажав кнопку Открыть опубликованный файл, а также опубликовать ссылку на него на другом сайте или форуме в виде http://pascalabc.net/WDE/?file=имя_файла.pas&lt;br /&gt;
&lt;br /&gt;
=== В течение какого времени на сервере хранятся опубликованные файлы ===&lt;br /&gt;
Несколько месяцев. Для зарегистрированных пользователей время хранения файлов на сервере больше.&lt;br /&gt;
&lt;br /&gt;
=== Насколько быстро выполняется программа ===&lt;br /&gt;
О, поверьте - очень быстро! Программа выполняется на сервере, сервер - мощный, куплен в рамках национального проекта &amp;quot;Образование&amp;quot; :)&lt;br /&gt;
Потому и быстро.&lt;br /&gt;
&lt;br /&gt;
Для примера: &lt;br /&gt;
[http://pascalabc.net/WDE/?file=Speed1.pas вот эта программа] иллюстрирует скорость вычислений.&lt;br /&gt;
Аналогичная программа, написанная на Delphi, работает процентов на 15 дольше. Попробуйте!&lt;br /&gt;
&lt;br /&gt;
=== Можно ли использовать модули (библиотеки) ===&lt;br /&gt;
Можно, но неудобно. По крайней мере, пока. Причина: модули приходится всякий раз создавать вручную во время сеанса и сохранять в каталоге сеанса пользователя под именем, совпадающим с именем модуля. Аналогичное можно сказать про dll библиотеки.&lt;br /&gt;
&lt;br /&gt;
А вот зарегистрированные пользователи работают каждый в своем каталоге, и проблем с сохранением модулей и библиотек нет.&lt;br /&gt;
&lt;br /&gt;
=== Для чего нужна регистрация ===&lt;br /&gt;
Зарегистрированные пользователи получают в свое полное распоряжение целый каталог на сервере, который не удаляется после завершения сеанса.&lt;br /&gt;
Кроме того, для них открывается ряд новых возможностей:&lt;br /&gt;
* переименование и удаление файлов&lt;br /&gt;
* создание каталогов и подкаталогов&lt;br /&gt;
* переименование и удаление каталогов&lt;br /&gt;
* длительное хранение опубликованных файлов&lt;br /&gt;
* открытие публичного доступа к своим файлам на чтение&lt;br /&gt;
* '''использование интерфейса учебных курсов'''&lt;br /&gt;
&lt;br /&gt;
=== Среда «зависла». Что делать?! ===&lt;br /&gt;
Скорее всего, произошел сбой сети или немного устал сервер. Например, Вы запустили компиляцию, а результата все нет и нет. &amp;lt;br /&amp;gt;&lt;br /&gt;
Найдите в меню редактора кнопочку &amp;lt;tt&amp;gt;«Прервать запросы на сервер»&amp;lt;/tt&amp;gt; и нажмите её. Это должно помочь. После этого повторите операцию еще раз. Если у Вас постоянные проблемы с сетью, то, возможно, придется использовать эту кнопку часто.&lt;br /&gt;
&lt;br /&gt;
Крайняя мера восстановления работоспособности среды — обновление страницы в браузере.&lt;br /&gt;
&lt;br /&gt;
=== Могу ли я работать с WDE без подключения к Интернету ===&lt;br /&gt;
Нет. Но чтобы запускать те же программы, что и в WDE, вы можете скачать и установить [http://pascalabc.net/ru/ssyilki-dlya-skachivaniya.html систему программирования PascalABC.NET] и работать в ней локально без подключения к Интернету.&lt;br /&gt;
&lt;br /&gt;
=== Я нашел ошибку! Куда писать? ===&lt;br /&gt;
Открываем вот эту страничку разработчиков:&lt;br /&gt;
http://pascalabc.net/razrabotchiki-pascalabc-net&lt;br /&gt;
И находим первый адрес.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=2244</id>
		<title>Другие технические решения</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=2244"/>
		<updated>2011-12-01T15:37:31Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Управление файлами */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:WDE]]&lt;br /&gt;
== Контроль запросов и ошибок ==&lt;br /&gt;
Если на сервере возникает необрабатываемое исключение, клиент не получает ответ на AJAX-запрос, и система перестает корректно работать.&lt;br /&gt;
&lt;br /&gt;
Необходимо сделать так, чтобы клиент '''всегда''' получал ответ на запрос серверу и корректно его обрабатывал.&lt;br /&gt;
&lt;br /&gt;
Для этого разработана следующая архитектура: &amp;lt;br /&amp;gt;&lt;br /&gt;
* монитор запросов к серверу на клиенте [JavaScript]&lt;br /&gt;
* использование try со специальным полиморфным возвращаемым объектом с сервера&lt;br /&gt;
* логирование непредвиденных исключений в БД&lt;br /&gt;
&lt;br /&gt;
=== Монитор запросов ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Вьюер сетевых операций&lt;br /&gt;
function QueryViewer{&lt;br /&gt;
// --------------------------------- Поля&lt;br /&gt;
    // Хэш операций&lt;br /&gt;
    this.QueriesHash;&lt;br /&gt;
    &lt;br /&gt;
// --------------------------------- Методы&lt;br /&gt;
    // Добавляет информацию о запросе&lt;br /&gt;
    this.AddQuery(queryID, queryInfo);&lt;br /&gt;
    // Возвращает информацию о запросе&lt;br /&gt;
    this.GetQueryInfo(queryID);           &lt;br /&gt;
    // Завершает запрос успешно&lt;br /&gt;
    this.QueryFinishSuccess(queryID); &lt;br /&gt;
    // Завершает запрос с ошибкой errorCode&lt;br /&gt;
    this.QueryFinishFailed(queryID, errorCode);&lt;br /&gt;
    // Удаляет информацию о запросе&lt;br /&gt;
    this.RemoveQuery(queryID);        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Информация о запросе&lt;br /&gt;
function QueryInfo {&lt;br /&gt;
    this.QueryType;                        // Тип запроса&lt;br /&gt;
    this.QueryData;                        // Связанные данные&lt;br /&gt;
    &lt;br /&gt;
    this.QueryState;                       // Статус запроса&lt;br /&gt;
    this.ErrorCode;                        // Код ошибки&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Визуализация пока простая, выводятся состояния запросов.&lt;br /&gt;
&lt;br /&gt;
=== Возвращаемые объекты ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    /// Возвращаемая клиенту информация&lt;br /&gt;
    public class ReturnInfo {&lt;br /&gt;
        /// Возвращаемые данные&lt;br /&gt;
        public Object Data&lt;br /&gt;
        /// Системная информация&lt;br /&gt;
        public SystemInfo SysInfo&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /// Системная информация&lt;br /&gt;
    public class SystemInfo { &lt;br /&gt;
        /// Код ошибки&lt;br /&gt;
        public ErrorCode ErrCode &lt;br /&gt;
        /// Идентификатор запроса&lt;br /&gt;
        public string QueryID&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Логирование исключений ===&lt;br /&gt;
В базу записывается следующая информация:&lt;br /&gt;
 имя пользователя&lt;br /&gt;
 тип операции&lt;br /&gt;
 время&lt;br /&gt;
 сообщение исключения&lt;br /&gt;
 имя файла, связанного с операцией (если оно есть)&lt;br /&gt;
 каталог&lt;br /&gt;
&lt;br /&gt;
=== Текущие сделанные запросы ===&lt;br /&gt;
 LoadFirstFileContent&lt;br /&gt;
 GetSessionExistingFileNames&lt;br /&gt;
 GetUserExistingFileItems&lt;br /&gt;
 GetSamplesExistingFileNames&lt;br /&gt;
 CheckNewFileName&lt;br /&gt;
 CheckPublishedFileName&lt;br /&gt;
 SaveDocument&lt;br /&gt;
&lt;br /&gt;
== Графика в WDE ==&lt;br /&gt;
До сих пор была возможность работы только с консольными приложениями. Однако, графика весьма заманчива. &lt;br /&gt;
Одно из возможных решений — использование HTML-элемента для работы с графикой '''&amp;lt;tt&amp;gt;&amp;lt;canvas&amp;gt;&amp;lt;/tt&amp;gt;'''.&lt;br /&gt;
&lt;br /&gt;
=== Canvas ===&lt;br /&gt;
Canvas предоставляет достаточно богатый набор возможностей работы с графикой: от рисования простых фигур до анимации и работы с клавиатурой и мышью.&lt;br /&gt;
Небольшой туториал находится [http://billmill.org/static/canvastutorial/ здесь]&lt;br /&gt;
&lt;br /&gt;
=== Графическое окно ===&lt;br /&gt;
Элемент Canvas размещается модели окна [http://prototype-window.xilinus.com/samples.html Prototype window]&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
* [https://developer.mozilla.org/en/Canvas_tutorial Canvas]&lt;br /&gt;
* [http://prototype-window.xilinus.com/samples.html Prototype window]&lt;br /&gt;
&lt;br /&gt;
== Горячие клавиши ==&lt;br /&gt;
Для горячих клавиш надо изменять код редактора&lt;br /&gt;
&lt;br /&gt;
== Подсветка синтаксиса ==&lt;br /&gt;
Глюк с размыванием текста в большинстве случаев возникает при переходе на новую строку. &amp;lt;br /&amp;gt;&lt;br /&gt;
Добавим восстановление синтаксиса после каждого Enter'а. Для этого надо залезть в код edit_area_full.js и в районе обработки клавиатуры добавить:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;if(letter==\&amp;quot;Entrer\&amp;quot;&amp;amp;&amp;amp;target_id==\&amp;quot;Â\&amp;quot;){if(eA.press_enter())use=Ë;eA.execCommand(\&amp;quot;resync_highlight\&amp;quot;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще бы можно при вставке кода это делать, но пока не знаю, как это определить.&lt;br /&gt;
&lt;br /&gt;
== Мультифайловость в редакторе ==&lt;br /&gt;
=== Описание ===&lt;br /&gt;
Работа с несколькими файлами одновременно вещь весьма полезная. Выбранный редактор с подсветкой синтаксиса '''EditArea''' эту возможность предоставляет. Однако, задать заголовок вкладки в нем можно только при её первом открытии, что, конечно, неудобно. В связи с этим в файл ''&amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt;'' были внесены поправки и добавлен метод для изменения не только содержимого вкладки, но и её заголовка.&lt;br /&gt;
&lt;br /&gt;
=== changeFile ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;changeFile&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
changeFile : function(id, newFile) {&lt;br /&gt;
    var curID = this.execCommand(id, 'curr_file')&lt;br /&gt;
        &lt;br /&gt;
    this.execCommand(id, 'change_curFileTabParams', newFile);&lt;br /&gt;
    this.setValue(id, newFile['text']);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== change_curFileTabParams ===&lt;br /&gt;
В содержимое &amp;lt;tt&amp;gt;editAreaLoader.iframe_script&amp;lt;/tt&amp;gt;, например, перед &amp;lt;tt&amp;gt;update_file&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.change_curFileTabParams=Ã(new_Ês){var curID = this.curr_file; this.update_file(curID, new_Ês); var elem=document.getElementById(this.files[curID]['html_id']); var html_curID='tab_file_'+encodeURIComponent(curID); this.filesIdAssoc[html_curID]=curID; this.files[curID]['html_id']= html_curID; var close=\&amp;quot;&amp;lt;img src=\\\&amp;quot;\&amp;quot;+È.eAL.baseURL+\&amp;quot;images/close.gif\\\&amp;quot; title=\\\&amp;quot;\&amp;quot;+Á.get_translation('close_tab','word')+\&amp;quot;\\\&amp;quot; onclick=\\\&amp;quot;eA.execCommand('close_file',eA.filesIdAssoc['\&amp;quot;+html_curID+\&amp;quot;']);return Ì;\\\&amp;quot; class=\\\&amp;quot;hidden\\\&amp;quot; onmouseover=\\\&amp;quot;Á.className=''\\\&amp;quot; onmouseout=\\\&amp;quot;Á.className='hidden'\\\&amp;quot; /&amp;gt;\&amp;quot;;elem.innerHTML=\&amp;quot;&amp;lt;a onclick=\\\&amp;quot;javascript:eA.execCommand('switch_to_file',eA.filesIdAssoc['\&amp;quot;+html_curID+\&amp;quot;']);\\\&amp;quot; selec=\\\&amp;quot;none\\\&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;span&amp;gt;&amp;lt;strong class=\\\&amp;quot;edited\\\&amp;quot;&amp;gt;*&amp;lt;/strong&amp;gt;\&amp;quot;+Á.files[curID]['title']+close+\&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/a&amp;gt;\&amp;quot;;};&amp;quot;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если работаете не с ''&amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt;'', в ''&amp;lt;tt&amp;gt;edit_area_functions.js&amp;lt;/tt&amp;gt;'':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
EditArea.prototype.change_curFileTabParams = function(new_Ês){&lt;br /&gt;
    var curID = this.curr_file;&lt;br /&gt;
    this.update_file(curID, new_Ês);&lt;br /&gt;
&lt;br /&gt;
    var elem = document.getElementById(this.files[curID]['html_id']);&lt;br /&gt;
    var html_curID = 'tab_file_' + encodeURIComponent(curID);&lt;br /&gt;
    this.filesIdAssoc[html_curID] = curID;&lt;br /&gt;
    this.files[curID]['html_id'] = html_curID;&lt;br /&gt;
    &lt;br /&gt;
    var close = &amp;quot;&amp;lt;img src=\&amp;quot;&amp;quot;+ parent.editAreaLoader.baseURL +&amp;quot;images/close.gif\&amp;quot; title=\&amp;quot;&amp;quot;+ this.get_translation('close_tab', 'word') +&amp;quot;\&amp;quot; onclick=\&amp;quot;editArea.execCommand('close_file', editArea.filesIdAssoc['&amp;quot;+ html_id +&amp;quot;']);return false;\&amp;quot; class=\&amp;quot;hidden\&amp;quot; onmouseover=\&amp;quot;this.className=''\&amp;quot; onmouseout=\&amp;quot;this.className='hidden'\&amp;quot; /&amp;gt;&amp;quot;;&lt;br /&gt;
    elem.innerHTML = &amp;quot;&amp;lt;a onclick=\&amp;quot;javascript:editArea.execCommand('switch_to_file', editArea.filesIdAssoc['&amp;quot;+ html_id +&amp;quot;']);\&amp;quot; selec=\&amp;quot;none\&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;span&amp;gt;&amp;lt;strong class=\&amp;quot;edited\&amp;quot;&amp;gt;*&amp;lt;/strong&amp;gt;&amp;quot;+ this.files[id]['title'] + close +&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Регулировка высоты редактора ==&lt;br /&gt;
Изначально в редакторе отсутствует возможность менять размер после загрузки страницы (кроме как воспользоваться кнопкой полного экрана).&lt;br /&gt;
&lt;br /&gt;
=== changeHeight ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;changeHeight &amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
changeHeight : function(id, newHeight) {&lt;br /&gt;
    this.execCommand(id, 'change_Height', newHeight);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== change_curFileTabParams ===&lt;br /&gt;
В содержимое &amp;lt;tt&amp;gt;editAreaLoader.iframe_script&amp;lt;/tt&amp;gt;, например, после &amp;lt;tt&amp;gt;update_size&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.change_Height=Ã(newHeight){var d=document,pd=È.document; if(typeof eAs !='undefined'&amp;amp;&amp;amp;eAs[eA.id]&amp;amp;&amp;amp;eAs[eA.id][\&amp;quot;displayed\&amp;quot;]==Ë){pd.getElementById(\&amp;quot;frame_\&amp;quot;+eA.id).Ç.height=newHeight;};};&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Заголовок текущей вкладки ==&lt;br /&gt;
== Описание ==&lt;br /&gt;
Отсутствует возможность узнать заголовок вкладки. Метод getCurrFileTitle и возвращает его.&lt;br /&gt;
&lt;br /&gt;
=== getCurrFileTitle===&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;getCurrFileTitle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
getCurrFileTitle : function (id) {&lt;br /&gt;
    var curID = this.execCommand(id, 'curr_file')&lt;br /&gt;
    return this.execCommand(id, 'get_currFileTitle', curID);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_currFileTitle ===&lt;br /&gt;
В содержимое &amp;lt;tt&amp;gt;editAreaLoader.iframe_script&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.get_currFileTitle=Ã(id){return Á.files[id]['title']};&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Состояние вкладки — изменено ли содержимое ==&lt;br /&gt;
=== Описание ===&lt;br /&gt;
Позволяет узнать, изменено ли содержимое вкладки по сравнению с сохраненной версией.&lt;br /&gt;
&lt;br /&gt;
=== currentFileIsEdited ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;currentFileIsEdited&amp;lt;/tt&amp;gt;, например, после стандартного метода &amp;lt;tt&amp;gt;setFileEditedMode&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
currentFileIsEdited : function (id) {&lt;br /&gt;
    var curID = this.execCommand(id, 'curr_file');&lt;br /&gt;
    var isEdited = this.execCommand(id, 'current_file_is_edited', curID);&lt;br /&gt;
    return isEdited;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== current_file_is_edited ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;current_file_is_edited&amp;lt;/tt&amp;gt;, например, перед стандартным методом &amp;lt;tt&amp;gt;set_file_edited_mode&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.current_file_is_edited=Ã(id){return Á.files[id]['edited'];};&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Переход на вкладку ==&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;switchToFile&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
switchToFile : function(id, tabID) {&lt;br /&gt;
    this.execCommand(id, 'switch_to_file', tabID);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Работа с единичными файлами (устарело) ==&lt;br /&gt;
Для работы с файлами (сохранение, переименование, удаление) удобно создать специальный объект, моделирующий файл. Нужно хранить:&lt;br /&gt;
* полное имя файла&lt;br /&gt;
* каталог (он же имя пользователя или id сессии)&lt;br /&gt;
* отображаемое имя (оно может быть слишком длинным для полного отображения)&lt;br /&gt;
* тип (сохраненный файл пользователя, или «висячий» («фантомный») файл примера)&lt;br /&gt;
* некоторые параметры редактора кода&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
// Файл&lt;br /&gt;
function File(&lt;br /&gt;
        pName,                  // имя файла&lt;br /&gt;
        pPath,                  // путь к файлу (пустая строка в случае основного каталога)&lt;br /&gt;
        pOwnerName,             // владелец (имя пользователя или гость)&lt;br /&gt;
        pIsPhantom,             // фантомный ли файл (фантомный - т.е. не сохраненный на сервере)&lt;br /&gt;
        pPhantomType            // тип фантомного файла (новый[new], пример[sample], опубликованный файл[public])&lt;br /&gt;
){&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------------- Поля&lt;br /&gt;
&lt;br /&gt;
    name;                              // имя файла&lt;br /&gt;
    viewName;                          // отображаемое имя файла (если не слишком длинное, то само pName)&lt;br /&gt;
    path;                              // путь к файлу&lt;br /&gt;
    fullName;                          // полное имя файла&lt;br /&gt;
    &lt;br /&gt;
    isByUser;                          // пользовательский ли это файл&lt;br /&gt;
    ownerName;                         // владелец (имя пользователя или ID сессии)&lt;br /&gt;
    &lt;br /&gt;
    isPhantom;                         // фантомный ли файл (фантомный - т.е. не сохраненный на сервере)&lt;br /&gt;
    phantomType;                       // тип фантомного файла (новый[new], пример[sample], опубликованный файл[public])&lt;br /&gt;
        &lt;br /&gt;
    isOpened;                          // открыт ли файл в редакторе&lt;br /&gt;
    tabID;                             // ID вкладки в редакторе&lt;br /&gt;
    &lt;br /&gt;
    sourceCode;                        // по необходимости можно использовать для хранения содержимого&lt;br /&gt;
    &lt;br /&gt;
// ----------------------------------------- Методы&lt;br /&gt;
    open;                              // открывает файл (в редакторе тоже)&lt;br /&gt;
    close;                             // закрывает файл (в редакторе тоже)&lt;br /&gt;
    active;                            // активирует файл в редакторе&lt;br /&gt;
    save;                              // устанавливает статус измененности в редакторе в ложь&lt;br /&gt;
    &lt;br /&gt;
    setFullName;                       // изменяет имя файла по полному имени&lt;br /&gt;
    setName;                           // изменяет имя файла&lt;br /&gt;
    &lt;br /&gt;
    updateTabTitle;                    // обновляет заголовок вкладки в соответствии с именем файла&lt;br /&gt;
    &lt;br /&gt;
    setSourceCode;                     // изменяет содержимое файла&lt;br /&gt;
    &lt;br /&gt;
    setNotPhantom;                     // изменяет статус файла на нефантомный&lt;br /&gt;
    setStatusClosed;                   // изменяет статус файла на закрытый&lt;br /&gt;
    setStatusOpened;                   // изменяет статус файла на открытый&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Управление файлами ==&lt;br /&gt;
Реализован '''браузер файлов''' — &amp;lt;tt&amp;gt;VirtualFileBrowser&amp;lt;/tt&amp;gt; и '''менеджер редактора''' — &amp;lt;tt&amp;gt;EditorManager&amp;lt;/tt&amp;gt;.&lt;br /&gt;
=== Браузер файлов ===&lt;br /&gt;
Занимается отображением содержимого каталогов. Предоставляет обработчики нажатий на кнопки.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Javascript&amp;quot;&amp;gt;&lt;br /&gt;
DivID         // ID блока, к которому привязывать браузер [string]&lt;br /&gt;
&lt;br /&gt;
UserName      // имя пользователя [string]&lt;br /&gt;
VarName       // Имя переменной, которая отвечает за данный браузер файлов [string]&lt;br /&gt;
&lt;br /&gt;
BrowserTitle  // Заголовок браузера файлов [string]    &lt;br /&gt;
    &lt;br /&gt;
CurrentDir    // текущий каталог [string]&lt;br /&gt;
LastChosenDir // последний выбранный каталог (для загрузки файлов) [string]&lt;br /&gt;
DirsHash      // хэш всех каталогов &lt;br /&gt;
dirNames      // список имен всех каталогов (вспомогательный) [Array&amp;lt;string&amp;gt;]&lt;br /&gt;
CurrentDirectoryContent      // текущий каталог [VirtualDirectoryContent]&lt;br /&gt;
    &lt;br /&gt;
UsedActions                  // Массив используемых операций с элементами браузера&lt;br /&gt;
&lt;br /&gt;
turnOffCheckboxes            // Выключать ли чекбоксы&lt;br /&gt;
&lt;br /&gt;
MAX_ITEMS_COUNT_ON_PAGE      // число отображаемых файлов без прокрутки&lt;br /&gt;
&lt;br /&gt;
// -------------------------------- Методы&lt;br /&gt;
Load                // Загрузить содержимое каталога&lt;br /&gt;
LoadParent          // Загрузить содержимое родительского каталога&lt;br /&gt;
    &lt;br /&gt;
Display             // Отобразить браузер&lt;br /&gt;
DisplayEmptyBrowser // Отображает заготовку для браузера&lt;br /&gt;
    &lt;br /&gt;
DirectoryIsLoaded            // Проверяет, есть ли данные по запрошенному каталогу&lt;br /&gt;
ParentDirectoryIsLoaded      // Проверяет, есть ли данные по родительскому каталогу&lt;br /&gt;
OpenDirectory                // Открывает запрошенный каталог&lt;br /&gt;
OpenParentDirectory          // Открывает родительский каталог&lt;br /&gt;
    &lt;br /&gt;
GetFullFileName              // По файлу в текущем каталоге браузере возвращает полное имя файла&lt;br /&gt;
GetFullDirectoryName         // По папке в текущем каталоге браузере возвращает полное имя папки&lt;br /&gt;
    &lt;br /&gt;
ContainsFile                 // Проверяет наличие файла в текущем каталоге&lt;br /&gt;
AddNewFile                   // Добавляет в браузер (текущий каталог) новый файл&lt;br /&gt;
RenameFile                   // Переименовывает файл &lt;br /&gt;
RemoveFile                   // Удаляет файл&lt;br /&gt;
ShareFile                    // Делает файл расшаренным&lt;br /&gt;
UnshareFile                  // Делает файл обычным&lt;br /&gt;
    &lt;br /&gt;
ContainsFolder               // Проверяет наличие каталога в текущем каталоге&lt;br /&gt;
AddNewFolder                 // Добавляет в браузер (текущий каталог) новый каталог&lt;br /&gt;
RenameFolder                 // Переименовывает каталог &lt;br /&gt;
RemoveFolder                 // Удаляет каталог&lt;br /&gt;
ShareFolder                  // Делает каталог расшаренным&lt;br /&gt;
UnshareFolder                // Делает каталог обычным&lt;br /&gt;
    &lt;br /&gt;
SetStatusInfo                // Устанавливает надпись статуса&lt;br /&gt;
    &lt;br /&gt;
GetCheckedFilesList          // Возвращает список отмеченных файлов (Array&amp;lt;LinkCheckboxPair&amp;gt;)&lt;br /&gt;
GetCheckedDirsList           // Возвращает список отмеченных каталогов (Array&amp;lt;LinkCheckboxPair&amp;gt;)&lt;br /&gt;
    &lt;br /&gt;
// -------------------------------- Callbacks&lt;br /&gt;
OnFileClick                     // Нажатие на файл&lt;br /&gt;
OnDirectoryClick                // Нажатие на каталог&lt;br /&gt;
OnParentDirectoryClick          // Нажатие на ссылку на родительский каталог&lt;br /&gt;
    &lt;br /&gt;
OnRenameFileButtonClick         // Нажатие на кнопку переименования файла&lt;br /&gt;
OnRemoveFileButtonClick         // Нажатие на кнопку удаления файлов&lt;br /&gt;
OnDownloadFilesButtonClick      // Нажатие на кнопку скачивания pas-файлов  &lt;br /&gt;
OnRenameFolderButtonClick       // Нажатие на кнопку переименования папки&lt;br /&gt;
OnRemoveFolderButtonClick       // Нажатие на кнопку удаления паки&lt;br /&gt;
OnNewFolderButtonClick          // Нажатие на кнопку создания новой папки&lt;br /&gt;
OnShareFilesButtonClick         // Нажатие на кнопку расшаривания файлов&lt;br /&gt;
OnGetSharedLinkButtonClick      // Нажатие на кнопку получения ссылки на расшаренный файл&lt;br /&gt;
OnUnshareFilesButtonClick       // Нажатие на кнопку закрытия доступа к файлам  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Менеджер редактора ===&lt;br /&gt;
Инкапсулирует работу с редактором. Файлы отдельно, редактор отдельно.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Javascript&amp;quot;&amp;gt;&lt;br /&gt;
UserFiles                     // Список пользовательских файлов в редакторе [hash&amp;lt;EditorFileData&amp;gt;]&lt;br /&gt;
SampleFiles                   // Список файлов примеров в редакторе [hash&amp;lt;EditorFileData&amp;gt;]&lt;br /&gt;
PublicFiles                   // Список публичных файлов в редакторе [hash&amp;lt;EditorFileData&amp;gt;]&lt;br /&gt;
SharedFiles                   // Список расшаренных файлов в редакторе [hash&amp;lt;EditorFileData&amp;gt;]&lt;br /&gt;
NewUserFiles                  // Список новых пользовательских файлов в редакторе [hash&amp;lt;EditorFileData&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
TabIDsHash                    // Владельцы и полные имена файлов по id вкладки [hash&amp;lt;EditorTabFileData&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
// -------------------------------- Методы&lt;br /&gt;
OpenFile                  // Открыть файл в редакторе&lt;br /&gt;
FileIsOpened              // Проверяет, открыт ли файл в редакторе&lt;br /&gt;
ActiveFile                // Делает активной вкладку заданного файла&lt;br /&gt;
CloseFile                 // Закрывает в редакторе заданный файл (меняет статус в менеджере)&lt;br /&gt;
CloseFileInEditor         // Закрывает заданный файл в самом редакторе&lt;br /&gt;
    &lt;br /&gt;
GetCurrFileData           // Возвращает информацию о текущем файле редактора&lt;br /&gt;
&lt;br /&gt;
SetFileEditStatusSaved    // Делает статус вкладки в редакторе нередактированной  &lt;br /&gt;
ChangeTabFileData         // Меняет для файла из текущей вкладки данные&lt;br /&gt;
&lt;br /&gt;
GetFileFromDirectory      // Возвращает данные открытого файла из заданного каталога (его или подкаталога)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=2243</id>
		<title>Другие технические решения</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=2243"/>
		<updated>2011-12-01T15:33:04Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Работа с единичными файлами */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:WDE]]&lt;br /&gt;
== Контроль запросов и ошибок ==&lt;br /&gt;
Если на сервере возникает необрабатываемое исключение, клиент не получает ответ на AJAX-запрос, и система перестает корректно работать.&lt;br /&gt;
&lt;br /&gt;
Необходимо сделать так, чтобы клиент '''всегда''' получал ответ на запрос серверу и корректно его обрабатывал.&lt;br /&gt;
&lt;br /&gt;
Для этого разработана следующая архитектура: &amp;lt;br /&amp;gt;&lt;br /&gt;
* монитор запросов к серверу на клиенте [JavaScript]&lt;br /&gt;
* использование try со специальным полиморфным возвращаемым объектом с сервера&lt;br /&gt;
* логирование непредвиденных исключений в БД&lt;br /&gt;
&lt;br /&gt;
=== Монитор запросов ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Вьюер сетевых операций&lt;br /&gt;
function QueryViewer{&lt;br /&gt;
// --------------------------------- Поля&lt;br /&gt;
    // Хэш операций&lt;br /&gt;
    this.QueriesHash;&lt;br /&gt;
    &lt;br /&gt;
// --------------------------------- Методы&lt;br /&gt;
    // Добавляет информацию о запросе&lt;br /&gt;
    this.AddQuery(queryID, queryInfo);&lt;br /&gt;
    // Возвращает информацию о запросе&lt;br /&gt;
    this.GetQueryInfo(queryID);           &lt;br /&gt;
    // Завершает запрос успешно&lt;br /&gt;
    this.QueryFinishSuccess(queryID); &lt;br /&gt;
    // Завершает запрос с ошибкой errorCode&lt;br /&gt;
    this.QueryFinishFailed(queryID, errorCode);&lt;br /&gt;
    // Удаляет информацию о запросе&lt;br /&gt;
    this.RemoveQuery(queryID);        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Информация о запросе&lt;br /&gt;
function QueryInfo {&lt;br /&gt;
    this.QueryType;                        // Тип запроса&lt;br /&gt;
    this.QueryData;                        // Связанные данные&lt;br /&gt;
    &lt;br /&gt;
    this.QueryState;                       // Статус запроса&lt;br /&gt;
    this.ErrorCode;                        // Код ошибки&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Визуализация пока простая, выводятся состояния запросов.&lt;br /&gt;
&lt;br /&gt;
=== Возвращаемые объекты ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    /// Возвращаемая клиенту информация&lt;br /&gt;
    public class ReturnInfo {&lt;br /&gt;
        /// Возвращаемые данные&lt;br /&gt;
        public Object Data&lt;br /&gt;
        /// Системная информация&lt;br /&gt;
        public SystemInfo SysInfo&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /// Системная информация&lt;br /&gt;
    public class SystemInfo { &lt;br /&gt;
        /// Код ошибки&lt;br /&gt;
        public ErrorCode ErrCode &lt;br /&gt;
        /// Идентификатор запроса&lt;br /&gt;
        public string QueryID&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Логирование исключений ===&lt;br /&gt;
В базу записывается следующая информация:&lt;br /&gt;
 имя пользователя&lt;br /&gt;
 тип операции&lt;br /&gt;
 время&lt;br /&gt;
 сообщение исключения&lt;br /&gt;
 имя файла, связанного с операцией (если оно есть)&lt;br /&gt;
 каталог&lt;br /&gt;
&lt;br /&gt;
=== Текущие сделанные запросы ===&lt;br /&gt;
 LoadFirstFileContent&lt;br /&gt;
 GetSessionExistingFileNames&lt;br /&gt;
 GetUserExistingFileItems&lt;br /&gt;
 GetSamplesExistingFileNames&lt;br /&gt;
 CheckNewFileName&lt;br /&gt;
 CheckPublishedFileName&lt;br /&gt;
 SaveDocument&lt;br /&gt;
&lt;br /&gt;
== Графика в WDE ==&lt;br /&gt;
До сих пор была возможность работы только с консольными приложениями. Однако, графика весьма заманчива. &lt;br /&gt;
Одно из возможных решений — использование HTML-элемента для работы с графикой '''&amp;lt;tt&amp;gt;&amp;lt;canvas&amp;gt;&amp;lt;/tt&amp;gt;'''.&lt;br /&gt;
&lt;br /&gt;
=== Canvas ===&lt;br /&gt;
Canvas предоставляет достаточно богатый набор возможностей работы с графикой: от рисования простых фигур до анимации и работы с клавиатурой и мышью.&lt;br /&gt;
Небольшой туториал находится [http://billmill.org/static/canvastutorial/ здесь]&lt;br /&gt;
&lt;br /&gt;
=== Графическое окно ===&lt;br /&gt;
Элемент Canvas размещается модели окна [http://prototype-window.xilinus.com/samples.html Prototype window]&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
* [https://developer.mozilla.org/en/Canvas_tutorial Canvas]&lt;br /&gt;
* [http://prototype-window.xilinus.com/samples.html Prototype window]&lt;br /&gt;
&lt;br /&gt;
== Горячие клавиши ==&lt;br /&gt;
Для горячих клавиш надо изменять код редактора&lt;br /&gt;
&lt;br /&gt;
== Подсветка синтаксиса ==&lt;br /&gt;
Глюк с размыванием текста в большинстве случаев возникает при переходе на новую строку. &amp;lt;br /&amp;gt;&lt;br /&gt;
Добавим восстановление синтаксиса после каждого Enter'а. Для этого надо залезть в код edit_area_full.js и в районе обработки клавиатуры добавить:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;if(letter==\&amp;quot;Entrer\&amp;quot;&amp;amp;&amp;amp;target_id==\&amp;quot;Â\&amp;quot;){if(eA.press_enter())use=Ë;eA.execCommand(\&amp;quot;resync_highlight\&amp;quot;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще бы можно при вставке кода это делать, но пока не знаю, как это определить.&lt;br /&gt;
&lt;br /&gt;
== Мультифайловость в редакторе ==&lt;br /&gt;
=== Описание ===&lt;br /&gt;
Работа с несколькими файлами одновременно вещь весьма полезная. Выбранный редактор с подсветкой синтаксиса '''EditArea''' эту возможность предоставляет. Однако, задать заголовок вкладки в нем можно только при её первом открытии, что, конечно, неудобно. В связи с этим в файл ''&amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt;'' были внесены поправки и добавлен метод для изменения не только содержимого вкладки, но и её заголовка.&lt;br /&gt;
&lt;br /&gt;
=== changeFile ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;changeFile&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
changeFile : function(id, newFile) {&lt;br /&gt;
    var curID = this.execCommand(id, 'curr_file')&lt;br /&gt;
        &lt;br /&gt;
    this.execCommand(id, 'change_curFileTabParams', newFile);&lt;br /&gt;
    this.setValue(id, newFile['text']);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== change_curFileTabParams ===&lt;br /&gt;
В содержимое &amp;lt;tt&amp;gt;editAreaLoader.iframe_script&amp;lt;/tt&amp;gt;, например, перед &amp;lt;tt&amp;gt;update_file&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.change_curFileTabParams=Ã(new_Ês){var curID = this.curr_file; this.update_file(curID, new_Ês); var elem=document.getElementById(this.files[curID]['html_id']); var html_curID='tab_file_'+encodeURIComponent(curID); this.filesIdAssoc[html_curID]=curID; this.files[curID]['html_id']= html_curID; var close=\&amp;quot;&amp;lt;img src=\\\&amp;quot;\&amp;quot;+È.eAL.baseURL+\&amp;quot;images/close.gif\\\&amp;quot; title=\\\&amp;quot;\&amp;quot;+Á.get_translation('close_tab','word')+\&amp;quot;\\\&amp;quot; onclick=\\\&amp;quot;eA.execCommand('close_file',eA.filesIdAssoc['\&amp;quot;+html_curID+\&amp;quot;']);return Ì;\\\&amp;quot; class=\\\&amp;quot;hidden\\\&amp;quot; onmouseover=\\\&amp;quot;Á.className=''\\\&amp;quot; onmouseout=\\\&amp;quot;Á.className='hidden'\\\&amp;quot; /&amp;gt;\&amp;quot;;elem.innerHTML=\&amp;quot;&amp;lt;a onclick=\\\&amp;quot;javascript:eA.execCommand('switch_to_file',eA.filesIdAssoc['\&amp;quot;+html_curID+\&amp;quot;']);\\\&amp;quot; selec=\\\&amp;quot;none\\\&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;span&amp;gt;&amp;lt;strong class=\\\&amp;quot;edited\\\&amp;quot;&amp;gt;*&amp;lt;/strong&amp;gt;\&amp;quot;+Á.files[curID]['title']+close+\&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/a&amp;gt;\&amp;quot;;};&amp;quot;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если работаете не с ''&amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt;'', в ''&amp;lt;tt&amp;gt;edit_area_functions.js&amp;lt;/tt&amp;gt;'':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
EditArea.prototype.change_curFileTabParams = function(new_Ês){&lt;br /&gt;
    var curID = this.curr_file;&lt;br /&gt;
    this.update_file(curID, new_Ês);&lt;br /&gt;
&lt;br /&gt;
    var elem = document.getElementById(this.files[curID]['html_id']);&lt;br /&gt;
    var html_curID = 'tab_file_' + encodeURIComponent(curID);&lt;br /&gt;
    this.filesIdAssoc[html_curID] = curID;&lt;br /&gt;
    this.files[curID]['html_id'] = html_curID;&lt;br /&gt;
    &lt;br /&gt;
    var close = &amp;quot;&amp;lt;img src=\&amp;quot;&amp;quot;+ parent.editAreaLoader.baseURL +&amp;quot;images/close.gif\&amp;quot; title=\&amp;quot;&amp;quot;+ this.get_translation('close_tab', 'word') +&amp;quot;\&amp;quot; onclick=\&amp;quot;editArea.execCommand('close_file', editArea.filesIdAssoc['&amp;quot;+ html_id +&amp;quot;']);return false;\&amp;quot; class=\&amp;quot;hidden\&amp;quot; onmouseover=\&amp;quot;this.className=''\&amp;quot; onmouseout=\&amp;quot;this.className='hidden'\&amp;quot; /&amp;gt;&amp;quot;;&lt;br /&gt;
    elem.innerHTML = &amp;quot;&amp;lt;a onclick=\&amp;quot;javascript:editArea.execCommand('switch_to_file', editArea.filesIdAssoc['&amp;quot;+ html_id +&amp;quot;']);\&amp;quot; selec=\&amp;quot;none\&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;span&amp;gt;&amp;lt;strong class=\&amp;quot;edited\&amp;quot;&amp;gt;*&amp;lt;/strong&amp;gt;&amp;quot;+ this.files[id]['title'] + close +&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Регулировка высоты редактора ==&lt;br /&gt;
Изначально в редакторе отсутствует возможность менять размер после загрузки страницы (кроме как воспользоваться кнопкой полного экрана).&lt;br /&gt;
&lt;br /&gt;
=== changeHeight ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;changeHeight &amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
changeHeight : function(id, newHeight) {&lt;br /&gt;
    this.execCommand(id, 'change_Height', newHeight);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== change_curFileTabParams ===&lt;br /&gt;
В содержимое &amp;lt;tt&amp;gt;editAreaLoader.iframe_script&amp;lt;/tt&amp;gt;, например, после &amp;lt;tt&amp;gt;update_size&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.change_Height=Ã(newHeight){var d=document,pd=È.document; if(typeof eAs !='undefined'&amp;amp;&amp;amp;eAs[eA.id]&amp;amp;&amp;amp;eAs[eA.id][\&amp;quot;displayed\&amp;quot;]==Ë){pd.getElementById(\&amp;quot;frame_\&amp;quot;+eA.id).Ç.height=newHeight;};};&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Заголовок текущей вкладки ==&lt;br /&gt;
== Описание ==&lt;br /&gt;
Отсутствует возможность узнать заголовок вкладки. Метод getCurrFileTitle и возвращает его.&lt;br /&gt;
&lt;br /&gt;
=== getCurrFileTitle===&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;getCurrFileTitle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
getCurrFileTitle : function (id) {&lt;br /&gt;
    var curID = this.execCommand(id, 'curr_file')&lt;br /&gt;
    return this.execCommand(id, 'get_currFileTitle', curID);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_currFileTitle ===&lt;br /&gt;
В содержимое &amp;lt;tt&amp;gt;editAreaLoader.iframe_script&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.get_currFileTitle=Ã(id){return Á.files[id]['title']};&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Состояние вкладки — изменено ли содержимое ==&lt;br /&gt;
=== Описание ===&lt;br /&gt;
Позволяет узнать, изменено ли содержимое вкладки по сравнению с сохраненной версией.&lt;br /&gt;
&lt;br /&gt;
=== currentFileIsEdited ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;currentFileIsEdited&amp;lt;/tt&amp;gt;, например, после стандартного метода &amp;lt;tt&amp;gt;setFileEditedMode&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
currentFileIsEdited : function (id) {&lt;br /&gt;
    var curID = this.execCommand(id, 'curr_file');&lt;br /&gt;
    var isEdited = this.execCommand(id, 'current_file_is_edited', curID);&lt;br /&gt;
    return isEdited;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== current_file_is_edited ===&lt;br /&gt;
В &amp;lt;tt&amp;gt;edit_area_full.js&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;current_file_is_edited&amp;lt;/tt&amp;gt;, например, перед стандартным методом &amp;lt;tt&amp;gt;set_file_edited_mode&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;EA.Ä.current_file_is_edited=Ã(id){return Á.files[id]['edited'];};&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Переход на вкладку ==&lt;br /&gt;
В &amp;lt;tt&amp;gt;EAL.prototype&amp;lt;/tt&amp;gt; добавлен метод &amp;lt;tt&amp;gt;switchToFile&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
switchToFile : function(id, tabID) {&lt;br /&gt;
    this.execCommand(id, 'switch_to_file', tabID);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Работа с единичными файлами (устарело) ==&lt;br /&gt;
Для работы с файлами (сохранение, переименование, удаление) удобно создать специальный объект, моделирующий файл. Нужно хранить:&lt;br /&gt;
* полное имя файла&lt;br /&gt;
* каталог (он же имя пользователя или id сессии)&lt;br /&gt;
* отображаемое имя (оно может быть слишком длинным для полного отображения)&lt;br /&gt;
* тип (сохраненный файл пользователя, или «висячий» («фантомный») файл примера)&lt;br /&gt;
* некоторые параметры редактора кода&lt;br /&gt;
&amp;lt;source lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
// Файл&lt;br /&gt;
function File(&lt;br /&gt;
        pName,                  // имя файла&lt;br /&gt;
        pPath,                  // путь к файлу (пустая строка в случае основного каталога)&lt;br /&gt;
        pOwnerName,             // владелец (имя пользователя или гость)&lt;br /&gt;
        pIsPhantom,             // фантомный ли файл (фантомный - т.е. не сохраненный на сервере)&lt;br /&gt;
        pPhantomType            // тип фантомного файла (новый[new], пример[sample], опубликованный файл[public])&lt;br /&gt;
){&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------------- Поля&lt;br /&gt;
&lt;br /&gt;
    name;                              // имя файла&lt;br /&gt;
    viewName;                          // отображаемое имя файла (если не слишком длинное, то само pName)&lt;br /&gt;
    path;                              // путь к файлу&lt;br /&gt;
    fullName;                          // полное имя файла&lt;br /&gt;
    &lt;br /&gt;
    isByUser;                          // пользовательский ли это файл&lt;br /&gt;
    ownerName;                         // владелец (имя пользователя или ID сессии)&lt;br /&gt;
    &lt;br /&gt;
    isPhantom;                         // фантомный ли файл (фантомный - т.е. не сохраненный на сервере)&lt;br /&gt;
    phantomType;                       // тип фантомного файла (новый[new], пример[sample], опубликованный файл[public])&lt;br /&gt;
        &lt;br /&gt;
    isOpened;                          // открыт ли файл в редакторе&lt;br /&gt;
    tabID;                             // ID вкладки в редакторе&lt;br /&gt;
    &lt;br /&gt;
    sourceCode;                        // по необходимости можно использовать для хранения содержимого&lt;br /&gt;
    &lt;br /&gt;
// ----------------------------------------- Методы&lt;br /&gt;
    open;                              // открывает файл (в редакторе тоже)&lt;br /&gt;
    close;                             // закрывает файл (в редакторе тоже)&lt;br /&gt;
    active;                            // активирует файл в редакторе&lt;br /&gt;
    save;                              // устанавливает статус измененности в редакторе в ложь&lt;br /&gt;
    &lt;br /&gt;
    setFullName;                       // изменяет имя файла по полному имени&lt;br /&gt;
    setName;                           // изменяет имя файла&lt;br /&gt;
    &lt;br /&gt;
    updateTabTitle;                    // обновляет заголовок вкладки в соответствии с именем файла&lt;br /&gt;
    &lt;br /&gt;
    setSourceCode;                     // изменяет содержимое файла&lt;br /&gt;
    &lt;br /&gt;
    setNotPhantom;                     // изменяет статус файла на нефантомный&lt;br /&gt;
    setStatusClosed;                   // изменяет статус файла на закрытый&lt;br /&gt;
    setStatusOpened;                   // изменяет статус файла на открытый&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Управление файлами ==&lt;br /&gt;
Реализован '''браузер файлов''' — &amp;lt;tt&amp;gt;VirtualFileBrowser&amp;lt;/tt&amp;gt; и '''менеджер редактора''' — &amp;lt;tt&amp;gt;EditorManager&amp;lt;/tt&amp;gt;.&lt;br /&gt;
=== Браузер файлов ===&lt;br /&gt;
Занимается отображением содержимого каталогов. Предоставляет обработчики нажатий на кнопки.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Javascript&amp;quot;&amp;gt;&lt;br /&gt;
DivID         // ID блока, к которому привязывать браузер [string]&lt;br /&gt;
&lt;br /&gt;
UserName      // имя пользователя [string]&lt;br /&gt;
VarName       // Имя переменной, которая отвечает за данный браузер файлов [string]&lt;br /&gt;
&lt;br /&gt;
BrowserTitle  // Заголовок браузера файлов [string]    &lt;br /&gt;
    &lt;br /&gt;
CurrentDir    // текущий каталог [string]&lt;br /&gt;
LastChosenDir // последний выбранный каталог (для загрузки файлов) [string]&lt;br /&gt;
DirsHash      // хэш всех каталогов &lt;br /&gt;
dirNames      // список имен всех каталогов (вспомогательный) [Array&amp;lt;string&amp;gt;]&lt;br /&gt;
CurrentDirectoryContent      // текущий каталог [VirtualDirectoryContent]&lt;br /&gt;
    &lt;br /&gt;
UsedActions                  // Массив используемых операций с элементами браузера&lt;br /&gt;
&lt;br /&gt;
turnOffCheckboxes            // Выключать ли чекбоксы&lt;br /&gt;
&lt;br /&gt;
MAX_ITEMS_COUNT_ON_PAGE      // число отображаемых файлов без прокрутки&lt;br /&gt;
&lt;br /&gt;
// -------------------------------- Методы&lt;br /&gt;
Load                // Загрузить содержимое каталога&lt;br /&gt;
LoadParent          // Загрузить содержимое родительского каталога&lt;br /&gt;
    &lt;br /&gt;
Display             // Отобразить браузер&lt;br /&gt;
DisplayEmptyBrowser // Отображает заготовку для браузера&lt;br /&gt;
    &lt;br /&gt;
DirectoryIsLoaded            // Проверяет, есть ли данные по запрошенному каталогу&lt;br /&gt;
ParentDirectoryIsLoaded      // Проверяет, есть ли данные по родительскому каталогу&lt;br /&gt;
OpenDirectory                // Открывает запрошенный каталог&lt;br /&gt;
OpenParentDirectory          // Открывает родительский каталог&lt;br /&gt;
    &lt;br /&gt;
GetFullFileName              // По файлу в текущем каталоге браузере возвращает полное имя файла&lt;br /&gt;
GetFullDirectoryName         // По папке в текущем каталоге браузере возвращает полное имя папки&lt;br /&gt;
    &lt;br /&gt;
ContainsFile                 // Проверяет наличие файла в текущем каталоге&lt;br /&gt;
AddNewFile                   // Добавляет в браузер (текущий каталог) новый файл&lt;br /&gt;
RenameFile                   // Переименовывает файл &lt;br /&gt;
RemoveFile                   // Удаляет файл&lt;br /&gt;
ShareFile                    // Делает файл расшаренным&lt;br /&gt;
UnshareFile                  // Делает файл обычным&lt;br /&gt;
    &lt;br /&gt;
ContainsFolder               // Проверяет наличие каталога в текущем каталоге&lt;br /&gt;
AddNewFolder                 // Добавляет в браузер (текущий каталог) новый каталог&lt;br /&gt;
RenameFolder                 // Переименовывает каталог &lt;br /&gt;
RemoveFolder                 // Удаляет каталог&lt;br /&gt;
ShareFolder                  // Делает каталог расшаренным&lt;br /&gt;
UnshareFolder                // Делает каталог обычным&lt;br /&gt;
    &lt;br /&gt;
SetStatusInfo                // Устанавливает надпись статуса&lt;br /&gt;
    &lt;br /&gt;
GetCheckedFilesList          // Возвращает список отмеченных файлов (Array&amp;lt;LinkCheckboxPair&amp;gt;)&lt;br /&gt;
GetCheckedDirsList           // Возвращает список отмеченных каталогов (Array&amp;lt;LinkCheckboxPair&amp;gt;)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
// -------------------------------- Callbacks&lt;br /&gt;
OnFileClick                     // Нажатие на файл&lt;br /&gt;
OnDirectoryClick                // Нажатие на каталог&lt;br /&gt;
OnParentDirectoryClick          // Нажатие на ссылку на родительский каталог&lt;br /&gt;
    &lt;br /&gt;
OnRenameFileButtonClick         // Нажатие на кнопку переименования файла&lt;br /&gt;
OnRemoveFileButtonClick         // Нажатие на кнопку удаления файлов&lt;br /&gt;
OnDownloadFilesButtonClick      // Нажатие на кнопку скачивания pas-файлов  &lt;br /&gt;
OnRenameFolderButtonClick       // Нажатие на кнопку переименования папки&lt;br /&gt;
OnRemoveFolderButtonClick       // Нажатие на кнопку удаления паки&lt;br /&gt;
OnNewFolderButtonClick          // Нажатие на кнопку создания новой папки&lt;br /&gt;
OnShareFilesButtonClick         // Нажатие на кнопку расшаривания файлов&lt;br /&gt;
OnGetSharedLinkButtonClick      // Нажатие на кнопку получения ссылки на расшаренный файл&lt;br /&gt;
OnUnshareFilesButtonClick       // Нажатие на кнопку закрытия доступа к файлам  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2226</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2226"/>
		<updated>2011-11-13T12:53:35Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Именование, форматирование */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III (''повышенной сложности'' — по желанию). Задания раздела IV нужно выполнить дома. &lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;br /&gt;
&lt;br /&gt;
== Занятие 2 (17 сентября) — Сравнения и логические операции ==&lt;br /&gt;
''Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.'' &lt;br /&gt;
 &lt;br /&gt;
''Используемые понятия'': логические операции '''not''', '''and''', '''or'''.  &lt;br /&gt;
&lt;br /&gt;
=== I. Основные задания ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A &amp;lt; B &amp;lt; C, и False в противном случае.&lt;br /&gt;
# Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== II. Задания повышенной сложности ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A &amp;lt; B и A &amp;gt; B.&lt;br /&gt;
# Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.&lt;br /&gt;
# Даны числа A, B, C (число A не равно 0). Рассмотрев ''дискриминант'' D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.&lt;br /&gt;
# Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== III. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.&lt;br /&gt;
# Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.&lt;br /&gt;
&lt;br /&gt;
== Не знаю, что ==&lt;br /&gt;
=== Поиск ошибок ===&lt;br /&gt;
Ошибки в программах — довольно частое явление. Нужно уметь находить и исправлять ошибки. К самым простым можно отнести ''ошибки синтаксиса''.&lt;br /&gt;
&lt;br /&gt;
Внимательно изучите [http://pascalabc.net/wiki/index.php/Начало._Возможные_ошибки#Неописанная_переменная эту страницу]. Там приведены самые распространенные ошибки начинающих программистов. Но ошибки могут быть самыми разнообразными. Часто в их устранении помогает компилятор, он выдает сообщение об ошибке. Но '''ожидания компилятора не всегда соответствуют нашим желаниям'''! &lt;br /&gt;
&lt;br /&gt;
Рассмотрим такую программу:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Компиляция приводит к ошибке: '''Ожидалось ':='''' во второй строке. Если броситься исправлять эту ошибку, не подумав, мы получим следующее:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a := real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ошибка: '''Ожидалась переменная'''. Может быть и не переменная (а выражение, например), но ожидался точно не тип. Вернемся к предыдущей программе и подумаем. &amp;lt;br /&amp;gt;&lt;br /&gt;
Очевидно, мы хотели описать переменную типа &amp;lt;tt&amp;gt;real&amp;lt;/tt&amp;gt;, но пропустили знак «:». &lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a: real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Отлично, работает.&lt;br /&gt;
&lt;br /&gt;
Не забыть&lt;br /&gt;
=== Именование, форматирование ===&lt;br /&gt;
Конечно, когда программист пишет программу, он в первую очередь хочет, чтобы она работала и работала правильно (если программист этого не хочет, значит это либо неправильный программист, который делает неправильные программы, либо хочет досадить начальству). Но еще программистам «иногда» приходится читать чужие программы. И вот тогда им хочется, чтобы эти программы читались легко.&lt;br /&gt;
&lt;br /&gt;
Вряд ли Вы сильно обрадуетесь, если коллеге вздумается вот так над Вами подшутить:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;var _1_,_1__,_1___,_1____,_2_,_2__,_:real;  &lt;br /&gt;
begin read(_1_,_1___,_1__,_1____,_2_,_2__);&lt;br /&gt;
_:=(5-_1_)/10;_*=_2_*_2_;&lt;br /&gt;
var __:=_1_+_1___;&lt;br /&gt;
__*=(_2_-3)*(_2_-3)*(_2_-3);_+=__*_2_;&lt;br /&gt;
_+=((_1____-_1__)/7)*_2__*(_2__+1)*(_2__+1);&lt;br /&gt;
_+=(_1____*_1____+_1__*_1__*_1__)*(3-_2__);&lt;br /&gt;
write(_);end.&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Между прочим, это еще ничего! Могло быть и хуже. Но все равно, более говорящие имена переменных не помешали бы. &amp;lt;br /&amp;gt;&lt;br /&gt;
Если коллега добрый, он признается, что программа могла выглядеть так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;var a,b,c,d,x,y,f:real;  &lt;br /&gt;
begin read(a,c,b,d,x,y);&lt;br /&gt;
f:=(5-a)/10;f*=x*x;&lt;br /&gt;
var f1:=a+c;&lt;br /&gt;
f1*=(x-3)*(x-3)*(x-3);f+=f1*x;&lt;br /&gt;
f+=((d-b)/7)*y*(y+1)*(y+1);&lt;br /&gt;
f+=(d*d+b*b*b)*(3-y);&lt;br /&gt;
write(f);end.&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь это стало похоже на вычисление некоторой странной функции двух переменных. Но читать это не очень-то удобно. Добавим простейшее форматирование:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;var &lt;br /&gt;
  a,b,c,d,x,y,f: real;  &lt;br /&gt;
begin &lt;br /&gt;
  read(a,c,b,d,x,y);&lt;br /&gt;
  f:=(5-a)/10;f*=x*x;&lt;br /&gt;
  var f1:=a+c;&lt;br /&gt;
  f1*=(x-3)*(x-3)*(x-3);f+=f1*x;&lt;br /&gt;
  f+=((d-b)/7)*y*(y+1)*(y+1);&lt;br /&gt;
  f+=(d*d+b*b*b)*(3-y);&lt;br /&gt;
  write(f);&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если разбить процесс вычисления функции на более очевидные шаги и использовать пробелы при форматировании операторов, можно получить, например, такой код:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;var&lt;br /&gt;
  a, b, c, d: real;&lt;br /&gt;
  x, y: real;&lt;br /&gt;
  f: real;&lt;br /&gt;
  &lt;br /&gt;
begin&lt;br /&gt;
  read(a, b, c, d);&lt;br /&gt;
  read(x, y);&lt;br /&gt;
  &lt;br /&gt;
  var add1 := ((5 - a) / 10) * x*x;&lt;br /&gt;
  var x1 := x - 3;&lt;br /&gt;
  var add2 := (a + c) * x * x1*x1*x1;&lt;br /&gt;
  var y1 := y + 1;&lt;br /&gt;
  var add3 := ((d - b) / 7) * y * y1*y1;&lt;br /&gt;
  var add4 := (d*d + b*b*b) * (3 - y);&lt;br /&gt;
  &lt;br /&gt;
  f := add1 + add2 + add3 + add4;&lt;br /&gt;
  write(f);&lt;br /&gt;
end.&amp;lt;/source&amp;gt;&lt;br /&gt;
Варианты могут быть разными. При желании можно даже использовать дополнительные переменные для &amp;lt;tt&amp;gt;x1&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;b&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt;. Неплохо бы еще добавить комментарий, в котором будет написано, что это за загадочная функция. &lt;br /&gt;
&lt;br /&gt;
Хорошие '''имена''' переменных (а также процедур, функций и типов), '''форматирование''' и '''комментирование''' кода упрощают процесс ''чтения'' и ''понимания'' кода. Начинать писать читабельный и понятный код надо с учебных программ. И не только потому, что преподавателю не очень-то хочется разбираться в стройных рядах закорючек, но и потому, что потом заниматься этим будет некогда. А самое страшное — это то, что, возможно, однажды придется разбираться в ''собственном'' коде.&lt;br /&gt;
&lt;br /&gt;
'''Примечание.''' Для разных языков программирования приняты разные правила форматирования и именования. Работа в команде разработчиков часто предполагает следование подобным правилам. Это не прихоть, а хороший способ упростить работу программистов с кодом. Это как бумажные письма! Гораздо приятней и проще читать письмо, написанное одним (причем понятным) почерком, чем перескакивать с одного на другой.&lt;br /&gt;
&lt;br /&gt;
Хорошая книга — Стив Макконелл, «Совершенный код».&lt;br /&gt;
&lt;br /&gt;
==== Список часто используемых английских слов ====&lt;br /&gt;
&lt;br /&gt;
=== Проверка правильности работы программы ===&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2170</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2170"/>
		<updated>2011-09-17T16:07:51Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Не знаю, что */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III (''повышенной сложности'' — по желанию). Задания раздела IV нужно выполнить дома. &lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;br /&gt;
&lt;br /&gt;
== Занятие 2 (17 сентября) — Сравнения и логические операции ==&lt;br /&gt;
''Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.'' &lt;br /&gt;
 &lt;br /&gt;
''Используемые понятия'': логические операции '''not''', '''and''', '''or'''.  &lt;br /&gt;
&lt;br /&gt;
=== I. Основные задания ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A &amp;lt; B &amp;lt; C, и False в противном случае.&lt;br /&gt;
# Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== II. Задания повышенной сложности ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A &amp;lt; B и A &amp;gt; B.&lt;br /&gt;
# Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.&lt;br /&gt;
# Даны числа A, B, C (число A не равно 0). Рассмотрев ''дискриминант'' D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.&lt;br /&gt;
# Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== III. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.&lt;br /&gt;
# Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.&lt;br /&gt;
&lt;br /&gt;
== Не знаю, что ==&lt;br /&gt;
=== Поиск ошибок ===&lt;br /&gt;
Ошибки в программах — довольно частое явление. Нужно уметь находить и исправлять ошибки. К самым простым можно отнести ''ошибки синтаксиса''.&lt;br /&gt;
&lt;br /&gt;
Внимательно изучите [http://pascalabc.net/wiki/index.php/Начало._Возможные_ошибки#Неописанная_переменная эту страницу]. Там приведены самые распространенные ошибки начинающих программистов. Но ошибки могут быть самыми разнообразными. Часто в их устранении помогает компилятор, он выдает сообщение об ошибке. Но '''ожидания компилятора не всегда соответствуют нашим желаниям'''! &lt;br /&gt;
&lt;br /&gt;
Рассмотрим такую программу:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Компиляция приводит к ошибке: '''Ожидалось ':='''' во второй строке. Если броситься исправлять эту ошибку, не подумав, мы получим следующее:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a := real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ошибка: '''Ожидалась переменная'''. Может быть и не переменная (а выражение, например), но ожидался точно не тип. Вернемся к предыдущей программе и подумаем. &amp;lt;br /&amp;gt;&lt;br /&gt;
Очевидно, мы хотели описать переменную типа &amp;lt;tt&amp;gt;real&amp;lt;/tt&amp;gt;, но пропустили знак «:». &lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a: real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Отлично, работает.&lt;br /&gt;
&lt;br /&gt;
Не забыть&lt;br /&gt;
=== Именование, форматирование ===&lt;br /&gt;
=== Проверка правильности работы программы ===&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2169</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2169"/>
		<updated>2011-09-15T17:56:07Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Поиск ошибок */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III (''повышенной сложности'' — по желанию). Задания раздела IV нужно выполнить дома. &lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;br /&gt;
&lt;br /&gt;
== Занятие 2 (17 сентября) — Сравнения и логические операции ==&lt;br /&gt;
''Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.'' &lt;br /&gt;
 &lt;br /&gt;
''Используемые понятия'': логические операции '''not''', '''and''', '''or'''.  &lt;br /&gt;
&lt;br /&gt;
=== I. Основные задания ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A &amp;lt; B &amp;lt; C, и False в противном случае.&lt;br /&gt;
# Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== II. Задания повышенной сложности ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A &amp;lt; B и A &amp;gt; B.&lt;br /&gt;
# Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.&lt;br /&gt;
# Даны числа A, B, C (число A не равно 0). Рассмотрев ''дискриминант'' D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.&lt;br /&gt;
# Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== III. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.&lt;br /&gt;
# Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.&lt;br /&gt;
&lt;br /&gt;
== Не знаю, что ==&lt;br /&gt;
=== Поиск ошибок ===&lt;br /&gt;
Ошибки в программах — довольно частое явление. Нужно уметь находить и исправлять ошибки. К самым простым можно отнести ''ошибки синтаксиса''.&lt;br /&gt;
&lt;br /&gt;
Внимательно изучите [http://pascalabc.net/wiki/index.php/Начало._Возможные_ошибки#Неописанная_переменная эту страницу]. Там приведены самые распространенные ошибки начинающих программистов. Но ошибки могут быть самыми разнообразными. Часто в их устранении помогает компилятор, он выдает сообщение об ошибке. Но '''ожидания компилятора не всегда соответствуют нашим желаниям'''! &lt;br /&gt;
&lt;br /&gt;
Рассмотрим такую программу:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Компиляция приводит к ошибке: '''Ожидалось ':='''' во второй строке. Если броситься исправлять эту ошибку, не подумав, мы получим следующее:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a := real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ошибка: '''Ожидалась переменная'''. Может быть и не переменная (а выражение, например), но ожидался точно не тип. Вернемся к предыдущей программе и подумаем. &amp;lt;br /&amp;gt;&lt;br /&gt;
Очевидно, мы хотели описать переменную типа &amp;lt;tt&amp;gt;real&amp;lt;/tt&amp;gt;, но пропустили знак «:». &lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a: real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Отлично, работает.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2164</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2164"/>
		<updated>2011-09-15T15:42:08Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Не знаю, что */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III (''повышенной сложности'' — по желанию). Задания раздела IV нужно выполнить дома. &lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;br /&gt;
&lt;br /&gt;
== Занятие 2 (17 сентября) — Сравнения и логические операции ==&lt;br /&gt;
''Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.'' &lt;br /&gt;
 &lt;br /&gt;
''Используемые понятия'': логические операции '''not''', '''and''', '''or'''.  &lt;br /&gt;
&lt;br /&gt;
=== I. Основные задания ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A &amp;lt; B &amp;lt; C, и False в противном случае.&lt;br /&gt;
# Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== II. Задания повышенной сложности ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A &amp;lt; B и A &amp;gt; B.&lt;br /&gt;
# Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.&lt;br /&gt;
# Даны числа A, B, C (число A не равно 0). Рассмотрев ''дискриминант'' D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.&lt;br /&gt;
# Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== III. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.&lt;br /&gt;
# Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.&lt;br /&gt;
&lt;br /&gt;
== Не знаю, что ==&lt;br /&gt;
=== Поиск ошибок ===&lt;br /&gt;
Ошибки в программах — довольно частое явление. Нужно уметь находить и исправлять ошибки. К самым простым можно отнести ''ошибки синтаксиса''.&lt;br /&gt;
&lt;br /&gt;
Внимательно изучите [http://pascalabc.net/wiki/index.php/Начало._Возможные_ошибки#Неописанная_переменная эту страницу]. Там приведены самые распространенные ошибки начинающих программистов. Но ошибки могут быть самыми разнообразными. Часто в их устранении помогает компилятор, он выдает сообщение об ошибке. Но '''ожидания компилятора не всегда соответствуют нашим желаниям'''! &lt;br /&gt;
&lt;br /&gt;
Рассмотрим такую программу:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Компиляция приводит к ошибке: '''Ожидалось ':='''' во второй строке. Если броситься исправлять эту ошибку, не подумав, мы получим следующее:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  a := real;&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ошибка: '''Ожидалась переменная'''. Ну, конечно, она ожидалась! Разве мы можем присвоить тип переменной? Вернемся к предыдущей программе и подумаем.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2163</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2163"/>
		<updated>2011-09-15T15:01:22Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* III. Задания на дом */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III (''повышенной сложности'' — по желанию). Задания раздела IV нужно выполнить дома. &lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;br /&gt;
&lt;br /&gt;
== Занятие 2 (17 сентября) — Сравнения и логические операции ==&lt;br /&gt;
''Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.'' &lt;br /&gt;
 &lt;br /&gt;
''Используемые понятия'': логические операции '''not''', '''and''', '''or'''.  &lt;br /&gt;
&lt;br /&gt;
=== I. Основные задания ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A &amp;lt; B &amp;lt; C, и False в противном случае.&lt;br /&gt;
# Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== II. Задания повышенной сложности ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A &amp;lt; B и A &amp;gt; B.&lt;br /&gt;
# Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.&lt;br /&gt;
# Даны числа A, B, C (число A не равно 0). Рассмотрев ''дискриминант'' D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.&lt;br /&gt;
# Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== III. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.&lt;br /&gt;
# Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.&lt;br /&gt;
&lt;br /&gt;
== Не знаю, что ==&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2146</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2146"/>
		<updated>2011-09-12T10:42:07Z</updated>

		<summary type="html">&lt;p&gt;Juliet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III (''повышенной сложности'' — по желанию). Задания раздела IV нужно выполнить дома. &lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;br /&gt;
&lt;br /&gt;
== Занятие 2 (17 сентября) — Сравнения и логические операции ==&lt;br /&gt;
''Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.'' &lt;br /&gt;
 &lt;br /&gt;
''Используемые понятия'': логические операции '''not''', '''and''', '''or'''.  &lt;br /&gt;
&lt;br /&gt;
=== I. Основные задания ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A &amp;lt; B &amp;lt; C, и False в противном случае.&lt;br /&gt;
# Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== II. Задания повышенной сложности ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A &amp;lt; B и A &amp;gt; B.&lt;br /&gt;
# Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.&lt;br /&gt;
# Даны числа A, B, C (число A не равно 0). Рассмотрев ''дискриминант'' D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.&lt;br /&gt;
# Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== III. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.&lt;br /&gt;
# Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2145</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2145"/>
		<updated>2011-09-12T10:20:20Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III. Задания раздела IV нужно выполнить дома.&lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;br /&gt;
&lt;br /&gt;
== Занятие 2 (17 сентября) — Сравнения и логические операции ==&lt;br /&gt;
''Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.'' &lt;br /&gt;
 &lt;br /&gt;
''Используемые понятия'': логические операции '''not''', '''and''', '''or'''.  &lt;br /&gt;
&lt;br /&gt;
=== I. Основные задания ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A &amp;lt; B &amp;lt; C, и False в противном случае.&lt;br /&gt;
# Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.&lt;br /&gt;
# Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== II. Задания повышенной сложности ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.&lt;br /&gt;
# Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A &amp;lt; B и A &amp;gt; B.&lt;br /&gt;
# Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.&lt;br /&gt;
# Даны числа A, B, C (число A не равно 0). Рассмотрев ''дискриминант'' D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.&lt;br /&gt;
# Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.&lt;br /&gt;
# Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае. &lt;br /&gt;
&lt;br /&gt;
=== III. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.&lt;br /&gt;
# Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.&lt;br /&gt;
# Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.&lt;br /&gt;
# Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.&lt;br /&gt;
# Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2144</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2144"/>
		<updated>2011-09-12T10:12:09Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* IV. Задания на дом */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III. Задания раздела IV нужно выполнить дома.&lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
	<entry>
		<id>https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2143</id>
		<title>Практикум на ЭВМ: I курс</title>
		<link rel="alternate" type="text/html" href="https://pascalabc.net/wiki/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D0%BD%D0%B0_%D0%AD%D0%92%D0%9C:_I_%D0%BA%D1%83%D1%80%D1%81&amp;diff=2143"/>
		<updated>2011-09-12T10:10:21Z</updated>

		<summary type="html">&lt;p&gt;Juliet: /* IV. Задания на дом */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''2011/2012 учебный год''&lt;br /&gt;
&lt;br /&gt;
= Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора =&lt;br /&gt;
== Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание ==&lt;br /&gt;
&lt;br /&gt;
Запустите среду программирования '''PascalABC.NET''' (Пуск / Программирование и ППП / Программирование / PascalABC.NET). &lt;br /&gt;
&lt;br /&gt;
Выполните в классе задания из разделов I-III. Задания раздела IV нужно выполнить дома.&lt;br /&gt;
&lt;br /&gt;
'''Рекомендации к выполнению'''&lt;br /&gt;
&lt;br /&gt;
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы. &lt;br /&gt;
&lt;br /&gt;
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений). &lt;br /&gt;
&lt;br /&gt;
в) Решения большинства заданий из этого пункта имеют следующую структуру:&lt;br /&gt;
# Ввод исходных данных&lt;br /&gt;
# Вычисление результата&lt;br /&gt;
# Вывод результата&lt;br /&gt;
&lt;br /&gt;
Блоки решения можно выделять пустыми строками и сопровождать комментариями.&lt;br /&gt;
&lt;br /&gt;
=== I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения  === &lt;br /&gt;
&lt;br /&gt;
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
  // Программа, печатающая приветствие - это комментарий к программе&lt;br /&gt;
  program Hello; &lt;br /&gt;
&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Привет, мир');&lt;br /&gt;
  end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Изучите пример, демонстрирующий использование вещественных переменных:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Использование вещественных переменных&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
  // Объявление переменной с одновременным присваиванием значения&lt;br /&gt;
  var a:real := 10.1;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
&lt;br /&gt;
  // Присваивание переменной нового значения&lt;br /&gt;
  a := 5;&lt;br /&gt;
  &lt;br /&gt;
  // Увеличение значения переменной&lt;br /&gt;
  a += 0.6;&lt;br /&gt;
  &lt;br /&gt;
  // Вывод значения переменной&lt;br /&gt;
  Writeln('a = ', a);&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление периметра квадрата по заданной стороне&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длину стороны квадрата:');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменной для хранения длины стороны&lt;br /&gt;
  var a: real;&lt;br /&gt;
  &lt;br /&gt;
  // Ввод длины стороны&lt;br /&gt;
  Read(a);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра&lt;br /&gt;
  var P: real := 4 * a;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;source lang=&amp;quot;Pascal&amp;quot;&amp;gt;&lt;br /&gt;
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
  Writeln('Введите длины катетов (два числа, разделенные пробелом):');&lt;br /&gt;
&lt;br /&gt;
  // Объявление переменных для хранения катетов&lt;br /&gt;
  var a, b: real;&lt;br /&gt;
  &lt;br /&gt;
  Read(a, b);&lt;br /&gt;
  &lt;br /&gt;
  // Тип переменной c определяется автоматически, как результат вычислений&lt;br /&gt;
  // sqrt - функция вычисления квадратного корня&lt;br /&gt;
  var c := sqrt(a*a + b*b);&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Гипотенуза c = ', c);&lt;br /&gt;
  &lt;br /&gt;
  // Вычисление периметра треугольника&lt;br /&gt;
  var P := a + b + c;&lt;br /&gt;
  &lt;br /&gt;
  Writeln('Периметр P = ', P);&lt;br /&gt;
end.&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислите синус и косинус угла, заданного в радианах.&lt;br /&gt;
&lt;br /&gt;
5. Найдите наибольшее целое число, которое не превышает корня заданного числа. &lt;br /&gt;
&lt;br /&gt;
6. Вычислите значение выражения по заданным a, b и c: &amp;lt;math&amp;gt;\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислите значение функции y = 4(x–3)&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt; – 7(x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== II. Операции с целыми числами ===&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': тип '''integer''', операции '''div''' (вычисление частного от деления) и '''mod''' (вычисления остатка от деления), стандартный вид числа (напр. &amp;lt;u&amp;gt;123&amp;lt;/u&amp;gt; = &amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;*100 + &amp;lt;u&amp;gt;2&amp;lt;/u&amp;gt;*10 + &amp;lt;u&amp;gt;3&amp;lt;/u&amp;gt;*1).&lt;br /&gt;
&lt;br /&gt;
'''Основные задания'''&lt;br /&gt;
&lt;br /&gt;
# Определить возраст человека в годах по возрасту, заданному в месяцах.&lt;br /&gt;
# Дано двузначное целое число. Вывести его правую и левую цифры.&lt;br /&gt;
# Дано трехзначное число. Вывести сумму и произведение его цифр.&lt;br /&gt;
# Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).&lt;br /&gt;
# Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.&lt;br /&gt;
# Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).&lt;br /&gt;
&lt;br /&gt;
'''Задания повышенной сложности'''&lt;br /&gt;
&lt;br /&gt;
''Используемые понятия'': [http://ru.wikipedia.org/wiki/Битовые_операции битовые операции].&lt;br /&gt;
&lt;br /&gt;
К ''битовым'' относятся бинарные операции '''and''', '''or''', '''not''', '''xor''', '''shl''', '''shr'''. Они производят побитовые манипуляции с операндами целого типа. Битовые операции '''and''', '''or''', '''not''' и '''xor''' осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции '''shl''' и '''shr''' выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:&lt;br /&gt;
&lt;br /&gt;
    00010101 '''and''' 00011001 = 00010001&lt;br /&gt;
    00010101 '''or''' 00011001 = 00011101&lt;br /&gt;
    00010101 '''xor''' 00011001 = 00001100&lt;br /&gt;
    '''not''' 00010101 = 11101010&lt;br /&gt;
    00010101 '''shl''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 10101000&lt;br /&gt;
    00010101 '''shr''' 3&amp;lt;sub&amp;gt;10&amp;lt;/sub&amp;gt; = 00000010&lt;br /&gt;
&lt;br /&gt;
(по умолчанию операнды и результат представлены в двоичной форме).&lt;br /&gt;
&lt;br /&gt;
В решениях удобно пользоваться [http://pascalabc.net/WDE/?file=00112.pas функцией перевода целого положительного числа в строковое двоичное представление] (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).&lt;br /&gt;
&lt;br /&gt;
'''Замечание''': для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.&lt;br /&gt;
&lt;br /&gt;
# Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)&lt;br /&gt;
# Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?&lt;br /&gt;
# Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.&lt;br /&gt;
# Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.&lt;br /&gt;
# Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).&lt;br /&gt;
# Дано целое число. Обнулить его младший бит. Установить его младший бит.&lt;br /&gt;
# Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.&lt;br /&gt;
# Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.&lt;br /&gt;
# Установить третий, пятый и седьмой биты в заданном числе.&lt;br /&gt;
# Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.&lt;br /&gt;
# Проверить, имеет ли заданное целое число вид 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; – 1.&lt;br /&gt;
# Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).&lt;br /&gt;
# Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.&lt;br /&gt;
&lt;br /&gt;
=== III. Операции с символами ===&lt;br /&gt;
&lt;br /&gt;
# Определить код заданного символа&lt;br /&gt;
# Вывести символ, следующий за данным&lt;br /&gt;
&lt;br /&gt;
=== IV. Задания на дом ===&lt;br /&gt;
&lt;br /&gt;
# Объявите вещественную переменную ''a'' со значением 1.5. Увеличьте ее в три раза и выведите новое значение.  Объявите переменную ''b'' и присвойте ей удвоенное значение переменной ''a'', выведите ее значение. Обнулите значение переменной ''a'' и вновь выведите ее значение. Вычислите сумму значений переменных ''a'' и ''b''.&lt;br /&gt;
# Дана длина ребра куба a. Найти объем куба и площадь его поверхности.&lt;br /&gt;
# Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: &amp;lt;math&amp;gt;\log_a b = \frac{\ln b}{\ln a}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.&lt;br /&gt;
# Вычислите значение выражения: &amp;lt;math&amp;gt;\frac{x+\sin x}{y-\sin z} + \ln(x+\sin x)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (&amp;lt;tt&amp;gt;const Pi=3.14159265;&amp;lt;/tt&amp;gt;) для числа π.&lt;br /&gt;
# Найти расстояние между двумя точками с заданными координатами &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_2, y_2)&amp;lt;/math&amp;gt; на плоскости. Расстояние вычисляется по формуле &amp;lt;math&amp;gt;d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны длины сторон треугольника. Вычислите его площадь, пользуясь ''формулой Герона'' &amp;lt;math&amp;gt;S=\sqrt{p(p-a)(p-b)(p-c)}&amp;lt;/math&amp;gt;, где p — полупериметр.&lt;br /&gt;
# Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением &amp;lt;math&amp;gt;t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.&lt;br /&gt;
# Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.&lt;br /&gt;
# Поменять местами значение переменных. То же, ''не используя'' вспомогательную переменную.&lt;br /&gt;
# Вывести символ, предшествующий данному&lt;br /&gt;
# Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.&lt;br /&gt;
# Определить последнюю цифру заданного целого числа.&lt;br /&gt;
# Даны три цифры, построить соответствующее трехзначное число.&lt;br /&gt;
# Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.&lt;br /&gt;
# Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.&lt;br /&gt;
# Дано трехзначное число. Обнулить в нем разряд десятков.&lt;br /&gt;
# Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.&lt;/div&gt;</summary>
		<author><name>Juliet</name></author>
	</entry>
</feed>