Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Delphi - "рулез форева"!   Найти похожие ветки 

 
Leonid Troyanovsky ©   (2010-02-16 22:18) [240]


> Игорь Шевченко ©   (16.02.10 21:41) [236]

> центральной частью функциональности, а не возвращение найден/не
> найден и места, куда вставить

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

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

Да, и уважаемый Alkid © палку-то перегнул, насчет by Ref,
бо, если у функций нет побочных эффектов, скажем, с
выделением памяти, то чего особенного она в системе изменит.

Заполняем мы буферы в функциях Win32, никто, вроде, не пострадал,
если, конечно, внимательно за размерами следил :)

--
Regards, LVT.


 
oxffff ©   (2010-02-16 22:35) [241]


> Alkid ©   (16.02.10 20:30) [220]
>
> > oxffff ©   (16.02.10 20:14) [213]
> > Но функциональным он не является. Зачем тогда F#?
>
> Он является как раз самым что ни на есть функциональным.
>  Это чистая функция высшего порядка - отвечает всем критериям
> "функциональной функции". То, что она написана на C# ничего
> не меняет. Функционально программировать можно на любом
> языке, на котором можно написать  чистую функцию. Просто
> в некоторых языках оставаться в парадигме ФП невыгодно из-
> за небольшой поддержки такого стиля в языке.
>
> Вот тебе пример ФП на старом добром С:
>
> int sum(int a, int b)
> {
>  return a + b;
> }
>
> int mul(int a, int b)
> {
>  return a * b;
> }
>
> int summAndMult(int a, int b, int c)
> {
> return sum(a, mult(b, c));
> }


Как он может являться функциональным языком, если в нем отсутствует много из разделов
http://fprog.ru/2009/issue3/eugene-kirpichov-elements-of-functional-languages?

Да в нем есть замыкания, анонимные функции, полувывод типов, лямбда выражения. Но где все остальное?


 
jack128_   (2010-02-16 22:39) [242]


> Да, и уважаемый Alkid © палку-то перегнул, насчет by Ref,
>
> бо, если у функций нет побочных эффектов, скажем, с
> выделением памяти, то чего особенного она в системе изменит.
>

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

int DoWork(ref int i)
{
   return i;
}

{
    i = 10;
    new Thread(() => {i = 20;}).Start();
    MessageBox.Show(DoWork(ref i).ToString());
}


 
Игорь Шевченко ©   (2010-02-16 22:40) [243]

Leonid Troyanovsky ©   (16.02.10 22:18) [240]

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


http://delphikingdom.ru/asp/viewitem.asp?catalogid=1392#SubSubHeader_2_6_6


 
Игорь Шевченко ©   (2010-02-16 22:42) [244]

jack128_   (16.02.10 22:39) [242]

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


 
Alkid ©   (2010-02-16 22:56) [245]


> vuk ©   (16.02.10 21:29) [232]
> to Alkid ©   (16.02.10 21:22) [231]:
>
> > Вся красота, о которой я говорю, не очень дружит с производительностью
>
> Зато красиво всё до опупения. Вот только отчего-то красивая
> машина не хочет летать красиво. Не дружит она с полетать.
> .. :)

Все аналогии лживы :)


 
Alkid ©   (2010-02-16 22:56) [246]


> Делфиец   (16.02.10 21:37) [235]
> Так на заметочку, а где вы работаете? А то когда буду безработным
> шляться, то быть в курсе о подобных конторах в которых прогеров
> в шеринги выстраивают ;-)

Не скажу :) Пусть будет сюрпризом


 
Leonid Troyanovsky ©   (2010-02-16 23:02) [247]


> Игорь Шевченко ©   (16.02.10 22:40) [243]

Хе-хе.

function Add: TSomeObject;
begin
 // Создание объекта
 Result := TSomeObject.Create;
 // Настройка объекта
 Result.ParentList := SomeList;
 // ... и другие свойства
 // Добавление его в список
 SomeList.Add(Result);
end;

Вроде у АП и на стене высекли: лучшая функция, возвращающая
объект - это конструктор.

А то, что "Очень тяжело: писать хороший код на исключениях"
это, конечно, да. Но, для объектной модели, в конечном счете,
полезней, бо прицел на обработку исключений заставляет
более тщательно подходить к проектированию классов.

--
Regards, LVT.


 
Alkid ©   (2010-02-16 23:03) [248]


> Игорь Шевченко ©   (16.02.10 21:41) [236]
> То есть, если ты делишь эту фунцию на две, ты дублируешь
> код, который по цитируемым тобой пророкам является грехом
> куда как большим, нежели возвращение двух значений :)

Ой ли :) "Дублируемый" код просто становится функцией и не дублируется. Что мешает написать функтор, ищущий позицию для элемента в заданном дереве и использовать его в функциях выборки элемента и модификации дерева?


> Э...в паскале тоже встречаются ? :) join, intersect  и union?

Про паскаль не скажу, хотя более чем уверен, что есть библиотеки, реализующие их. Собственно я к чему - весь этот linq - это не более, чем  .net-воплощение аппарата работы со множествами, который сам по себе ортогонален языку. Этот аппарат очень полезен, если в программе надо обрабатывать коллекции объектов.


> делфиец   (16.02.10 21:56) [237]
> да почти весь WINAPI так устроен, кстати и это тоже придумали те же умные парни из Microsoft .

Это были ДРУГИЕ парни из MS :) Не молодцы. В адрес Win32 не плюнул только ленивый.


> Вы Alkid © представляете себе, что было бы, если бы эти
> парни из Microsoft дробили бы все свои подобные функиции
> на двое?

Да. Получился бы API похожий на юниксовый.


 
oxffff ©   (2010-02-16 23:09) [249]


> Alkid ©   (16.02.10 23:03) [248]
>
> > Игорь Шевченко ©   (16.02.10 21:41) [236]
> > То есть, если ты делишь эту фунцию на две, ты дублируешь
>
> > код, который по цитируемым тобой пророкам является грехом
>
> > куда как большим, нежели возвращение двух значений :)
>
> Ой ли :) "Дублируемый" код просто становится функцией и
> не дублируется. Что мешает написать функтор, ищущий позицию
> для элемента в заданном дереве и использовать его в функциях
> выборки элемента и модификации дерева?


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


 
Alkid ©   (2010-02-16 23:09) [250]


> Leonid Troyanovsky ©   (16.02.10 22:18) [240]
> Да, и уважаемый Alkid © палку-то перегнул, насчет by Ref,
>
> бо, если у функций нет побочных эффектов, скажем, с
> выделением памяти, то чего особенного она в системе изменит.

By-ref by-refу рознь. Если объект передается по ссылке с запретом на модификацию, то ничего плохого я в этом не усматриваю.


> oxffff ©   (16.02.10 22:35) [241]
> Да в нем есть замыкания, анонимные функции, полувывод типов,
>  лямбда выражения. Но где все остальное?

Ты это про С или С#? В любом случае, писать в функциональном стиле можно и не на функциональном языке. Просто поддержки для такого стиля в нем будет меньше.


 
Alkid ©   (2010-02-16 23:11) [251]


> Игорь Шевченко ©   (16.02.10 21:30) [233]


> http://local.joelonsoftware.com/wiki/%D0%9D%D0%B5_%D0%B4%D0%B0%D0%B9%D1%82%D0%B5_%D0%90%D1%81%D1%82%D1%80%D0%BE%D0%BD%D0%B0%D0%B2%D1%82%D0%B0%D0%BC_%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B2%D0%B0%D1%81_%D0%B7%D0%B0%D0%BF%D1%83%D0%B3%D0%B0%D1%82%D1%8C
>

Читал-читал.


> Как это ни странно, в ряде случаев отлично дружит. Особенно
> если объекты не городить :) Сокрытие информации и разделение
> обязанностей прекрасно можно реализовать и без ООП, чему
> опыт исходного кода Unix уже лет 30 с копейками как свидетельствует.

Да чего ты к объектам прицепился-то? Я вообще-то не ООП тут продвигаю :)


 
Alkid ©   (2010-02-16 23:13) [252]


> oxffff ©   (16.02.10 23:09) [249]
> > Ой ли :) "Дублируемый" код просто становится функцией
> и
> > не дублируется. Что мешает написать функтор, ищущий позицию
>
> > для элемента в заданном дереве и использовать его в функциях
>
> > выборки элемента и модификации дерева?
>
> Все бы здорово, только не хорошо чтобы тяжелый код вызывался
> по два раза. Там где он очевидно должен вызываться только
> один раз.

Я уже оговорился насчет производительности :) Если стоят приоритетные требования по оптимизации, то они сметают многие принципы структурирования кода.


 
Игорь Шевченко ©   (2010-02-16 23:14) [253]

Alkid ©   (16.02.10 23:03) [248]


> Ой ли :) "Дублируемый" код просто становится функцией и
> не дублируется. Что мешает написать функтор, ищущий позицию
> для элемента в заданном дереве и использовать его в функциях
> выборки элемента и модификации дерева?


Я наверное чего-то не понимаю. Функция, приведенная мной и vuk-ом делает два дела - возвращает, найден или нет указанный ключ в массиве, и позицию либо найденного ключа, либо для вставки ключа в массив.
То есть, позиция возвращается в любом случае, найден ключ или не найден.

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

Как ты предлагаешь разбить ?
Исходная функция - вот она:

function TStringList.Find(const S: string; var Index: Integer): Boolean;
var
 L, H, I, C: Integer;
begin
 Result := False;
 L := 0;
 H := FCount - 1;
 while L <= H do
 begin
   I := (L + H) shr 1;
   C := CompareStrings(FList^[I].FString, S);
   if C < 0 then L := I + 1 else
   begin
     H := I - 1;
     if C = 0 then
     begin
       Result := True;
       if Duplicates <> dupAccept then L := I;
     end;
   end;
 end;
 Index := L;
end;


Leonid Troyanovsky ©   (16.02.10 23:02) [247]


> Вроде у АП и на стене высекли: лучшая функция, возвращающая
> объект - это конструктор.


Дальше приведенного тобой кода тоже стоит почитать - неплохая статья :)


 
oxffff ©   (2010-02-16 23:16) [254]


> > oxffff ©   (16.02.10 22:35) [241]
> > Да в нем есть замыкания, анонимные функции, полувывод
> типов,
> >  лямбда выражения. Но где все остальное?
>
> Ты это про С или С#? В любом случае, писать в функциональном
> стиле можно и не на функциональном языке. Просто поддержки
> для такого стиля в нем будет меньше.


Я про с#. Писать можно только в полуфункциональном стиле.
А вызов чистых функций и функций высших порядков это элементы ФП. Но не ФП.


 
Игорь Шевченко ©   (2010-02-16 23:21) [255]

Alkid ©   (16.02.10 23:11) [251]


> Да чего ты к объектам прицепился-то? Я вообще-то не ООП
> тут продвигаю :)


Я может быть тебя не так понял, а разве то, что ты продвигаешь, не является надстройкой над ООП и имеет смысл само по себе ? :)


 
Leonid Troyanovsky ©   (2010-02-16 23:37) [256]


> Alkid ©   (16.02.10 23:09) [250]

> By-ref by-refу рознь.

Значит дело не в by ref.
Держать ссылку на объект можно, скажем, и в поле.
Просто, соглашение такое есть (негласное?):
если мы собираемся только читать (ничего в состоянии системы не меняя), то методом будет функция, а если менять (хотя бы состояние самого объекта) - то процедура.
Геттерам не запрещены побочные эффекты, однако, это, IMHO,
не используют. Ну, или, скажем, не надо использовать.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2010-02-17 00:06) [257]


> Игорь Шевченко ©   (16.02.10 23:14) [253]

> Дальше приведенного тобой кода тоже стоит почитать - неплохая
> статья :)

Я почитал. Большой материал переварен.
Примеры мне только не очень, бо не надо было регулярные функции
с объектами мешать. Начал бы прямо с конструктора/деструктора,
было б проще объяснять, да и полезней.

--
Regards, LVT.


 
Alkid ©   (2010-02-17 00:11) [258]


> Игорь Шевченко ©   (16.02.10 23:14) [253]
> Я наверное чего-то не понимаю. Функция, приведенная мной
> и vuk-ом делает два дела - возвращает, найден или нет указанный
> ключ в массиве, и позицию либо найденного ключа, либо для
> вставки ключа в массив.
> То есть, позиция возвращается в любом случае, найден ключ
> или не найден.

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

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


 
Alkid ©   (2010-02-17 00:12) [259]


> oxffff ©   (16.02.10 23:16) [254]
> Я про с#. Писать можно только в полуфункциональном стиле.
> А вызов чистых функций и функций высших порядков это элементы
> ФП. Но не ФП.

Что есть ФП, а что не есть - тема для холиваров. Приведенная тобой статья не является стандартом :)


 
Alkid ©   (2010-02-17 00:14) [260]


> Игорь Шевченко ©   (16.02.10 23:21) [255]
> Я может быть тебя не так понял, а разве то, что ты продвигаешь,
>  не является надстройкой над ООП и имеет смысл само по себе
> ? :)

Ты меня не так понял. Я сейчас продвигаю идеи функционального программирования, которое появилось задолго до ООП и имеет, в отличие от ООП, строгую формальную базу. При этом хочу оговориться (а то потом не так поймёте :) ) - я не продвигаю ФП как "серебрянную пулю" и единственно верную парадигму.


 
Alkid ©   (2010-02-17 00:18) [261]


> Leonid Troyanovsky ©   (16.02.10 23:37) [256]

Дело не в by-ref. Дело в модификации переданных параметров. Я утверждаю, что при прочих равных функция, которая не производит модификации параметров (как и других side-effect`ов) лучше, чем аналогичная по смыслу функция, которая опирается на side-effect`ы и/или изменение параметров. Причем модификацию параметров я считаю бОльшим злом, чем другой побочный эффект.

Если же надо вернуть несколько значений (и это оправдано! Помним о code-smell), то лучше использовать другие средства - структуры, кортежи. Если они есть в языке, конечно.


 
Leonid Troyanovsky ©   (2010-02-17 00:39) [262]


> Alkid ©   (17.02.10 00:18) [261]

> на side-effect`ы и/или изменение параметров. Причем модификацию
> параметров я считаю бОльшим злом, чем другой побочный эффект.

А мне большим злом представляется другие побочные эффекты,
особенно, если они еще и припрятаны.
Ну, а против модификации параметров возражать не буду,
если это простые типы (Integer в т.ч.).

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

Допустим, что Дельфи может вернуть, скажем, TStrings.
Но, я такую функцию писать не буду.
Это будет procedure FillStrings(Strings: TStrings)

--
Regards, LVT.


 
oxffff ©   (2010-02-17 00:58) [263]


> Alkid ©   (17.02.10 00:18) [261]
>
> > Leonid Troyanovsky ©   (16.02.10 23:37) [256]
>
> Дело не в by-ref. Дело в модификации переданных параметров.
>  Я утверждаю, что при прочих равных функция, которая не
> производит модификации параметров (как и других side-effect`ов)
> лучше, чем аналогичная по смыслу функция, которая опирается
> на side-effect`ы и/или изменение параметров. Причем модификацию
> параметров я считаю бОльшим злом, чем другой побочный эффект.
>  


А в чем же этот эффект проявляется?
Здается мне что он окажет некое воздействие на правила B и N редукции термов и сведет на нет или крайне усложнит алгоритм мемоизации.
Или засада в другом?


 
oxffff ©   (2010-02-17 01:05) [264]

>Alkid ©  
Насчет имутабильности переменнных. Мне это знакомо с точки зрения теории типов. Где изменчивость оказывает сильное влияния на диапазон подтипов. Но это из другой области.


 
Германн ©   (2010-02-17 01:12) [265]

Вот уж не ожидал такого обсуждения. :)


 
vuk ©   (2010-02-17 01:13) [266]

to Alkid ©   (17.02.10 00:11) [258]:

>  Ее проблема в том, что она всегда возвращает индекс, даже
> если его возврат бессмысленнен.

А вот нифига. Если элемент не найден, то индекс в этой функции все равно имеет смысл.


 
Petr V. Abramov ©   (2010-02-17 01:14) [267]


> Leonid Troyanovsky ©   (17.02.10 00:39) [262]


> Возвращаемые результатом структуры не люблю, они тревожат
> мое подсознание (что со всем этим добром делать?).
> А если за ними стоит выделение памяти - считаю такой возврат
> недопустимым.

считай, но не огульно :)
главное, соблюдать принцип "кто ужинает, девушку, тот ее и танцует", соотвественно, кто память выделяет, тот ее и освобождает. Если новая структура передается куда-то дальше по ходу API,  меньше ошибок из серии "за был освободить ltDmMessage, которое в структуре стоит 25-м и вообще for future use и вообще ради лулзов". CloseLtHandle и забыл.
При условии незабывания вызова CloseLtHandle, еснно, но этот случай требует лечения с непредсказуемым (лечения) результатом.


 
Германн ©   (2010-02-17 01:16) [268]

Удалено модератором


 
Petr V. Abramov ©   (2010-02-17 01:39) [269]

Удалено модератором


 
Германн ©   (2010-02-17 02:01) [270]

Удалено модератором


 
Petr V. Abramov ©   (2010-02-17 02:09) [271]

Удалено модератором


 
Германн ©   (2010-02-17 02:18) [272]

Удалено модератором


 
Alkid ©   (2010-02-17 05:17) [273]


> vuk ©   (17.02.10 01:13) [266]
> А вот нифига. Если элемент не найден, то индекс в этой функции
> все равно имеет смысл.

Опять моя внимательность меня подводит :(


 
Alkid ©   (2010-02-17 05:19) [274]


> Leonid Troyanovsky ©   (17.02.10 00:39) [262]

Можно поподробнее объяснить, почему против возврата сложных типов из функций?


 
Alkid ©   (2010-02-17 05:28) [275]


> oxffff ©   (17.02.10 00:58) [263]
> Здается мне что он окажет некое воздействие на правила B
> и N редукции термов и сведет на нет или крайне усложнит
> алгоритм мемоизации.
> Или засада в другом?

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

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


 
Kerk ©   (2010-02-17 09:26) [276]


> Игорь Шевченко ©   (16.02.10 20:24) [218]
>
> Kerk ©   (16.02.10 20:17) [215]
>
> > Я не доверяю GC почему-то
>
> то есть, на всяких там перлах и прочих скриптовых языках
> ты пишешь исключительно под наркозом ? :)

Приходится с этим мириться :)
Но при мысли об этом испытываю дискомфорт.


 
Игорь Шевченко ©   (2010-02-17 14:03) [277]

Alkid ©   (17.02.10 00:11) [258]


>  Должно быть так: если искомого элемента нет, то индекс
> в принципе нельзя получить и использовать


Нет, не должно быть так. Почитай внимательно. Функция ВСЕГДА возвращает индекс, либо найденного элемента, либо места, куда надо вставить элемент.


 
Leonid Troyanovsky ©   (2010-02-17 18:07) [278]


> Alkid ©   (17.02.10 05:19) [274]

> Можно поподробнее объяснить, почему против возврата сложных
> типов из функций?

Структуры неудобно.
Вместо if f(x) или case of f(x) нужно что-то типа with f(x).
Присваивать локальной переменной ради того, чтобы
воспользоваться результатом if p.y? Лишние движения.

Кроме того, структуры редко когда нужны сами по себе,
обычно они идут вкупе с буфером, стримом.

Про классы я уже говорил. Остаются String & Variant.
Ну, это кто как любит, только не забывать про IsMultithread.

А честные параметры Int*, Bool*, Float &etc и даже статические
массивы  - почему бы и нет? Возвращаемый функцией
результат лучше их только тем, что лежит в регистре.
Лучше это, конечно, если это не глобальные переменные.

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

--
Regards, LVT.


 
vuk ©   (2010-02-17 18:27) [279]

to Leonid Troyanovsky ©   (17.02.10 18:07) [278]:

> Структуры неудобно.

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


> Присваивать локальной переменной ради того, чтобы
> воспользоваться результатом if p.y? Лишние движения.


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


 
Leonid Troyanovsky ©   (2010-02-17 18:39) [280]


> Petr V. Abramov ©   (17.02.10 01:14) [267]

> и танцует", соотвественно, кто память выделяет, тот ее и
> освобождает.

Мой алгоритм проще запомнить: если хочешь потанцевать,
то для начала накорми. Память распредели, определи локальные
переменные для параметров и т.д. и т.п.
{MS не зря API так строил, и вовсе не потому, что там, скажем, засели
враги ООП или ФП, или просто двоечники, а что подругому было б хуже}
Т.е.,  выделяется и освобождается все в одном процедурном блоке,
так и следить легче за парами New/Dispose, Create/Free, да и finally будет
на месте.

Ну, а тому, кто забывает CloseHandle, надо потихоньку, понемножку
где-нибудь что-нибудь отрывать, пока, гад, не научится.

--
Regards, LVT.



Страницы: 1 2 3 4 5 6 7 8 вся ветка

Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 1.1 MB
Время: 0.103 c
15-1271077786
12
2010-04-12 17:09
2010.08.27
Зачем сия картинка? http://delphimaster.ru/i/1x1.gif


6-1223267358
JohnKorsh
2008-10-06 08:29
2010.08.27
Индикация наличия пакета.


2-1269455858
plazmaser
2010-03-24 21:37
2010.08.27
строки в ексель


2-1275314647
SIV5000
2010-05-31 18:04
2010.08.27
TTimer


15-1263677426
Юрий
2010-01-17 00:30
2010.08.27
С днем рождения ! 17 января 2010 воскресенье





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский