LINUX.ORG.RU

Зачем нужны динамические языки?


0

0

Собственно не пойму. Вроде обещают более быструю разработку, но за счет чего? За счет того, что не надо писать тип при объявлении переменной? Так это ведь глупость, никакой скорости разработки это не добавит. Естественно, такие языки можно использовать только для прототипирования, но не проще ли сразу использовать язык, который обеспечит и скорость разработки и скорость выполнения, тем более, что динамический язык принципиально нельзя ускорить (имеется ввиду компилятор)? (я имею ввиду современные языки с выводом типов)

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

Мне, вообще, кажется, это какая-то болезнь головы у людей; возможно, спровоцированная глубоким изучением плюсов. Повреждается голова от такого. Или просто ничего кроме факториалов в 10 видах не писали? Мир он знаете, не статичен никоим образом, а программирование это как раз моделирование этого мира(разумеется, некоторые виды программисткой деятельности к моделированию относятся очень слабо - например, написание факториалов на хаскеле, или бухгалтерских приложений с гуём на жабе).

А шаблоны для "метапрограммирования" это курам на смех.

guest-3484-2009
()
Ответ на: комментарий от mv

> Ну, не знаю, расширь сознание как-нибудь :)

Ты tailgunner-а не пугай. Его испугать очень легко. Я вот даже немного испугался от твоего примера.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от guest-3484-2009

> Вот после того, как хаскелеводы у себя что-нибудь похожее на MOP из коммонлиспа сделают

Зачем им это?

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

> Бл*дь, какой ужас. Я ночь спать не смогу теперь.

К счастью, к реальности это отношения не имеет. Так что, спи спокойно.

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

> к реальности это отношения не имеет

Если это технически возможно, это обязательно кто-нибудь попробует. И врата ада разверзнутся O_o

tailgunner ★★★★★
()
Ответ на: комментарий от guest-3484-2009

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

1) Объекты не нужны

2) А в чём проблема, собственно? Думаю, в Олеговскую объектную систему MOP встроится элементарно.

> Мир он знаете, не статичен никоим образом, а программирование это как раз моделирование этого мира

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

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

> 2. Жаль что они сделали 15-минутное введение только для ML-щиков. Я его очень плохо знаю.

Ну почему же, там есть 15 минут и для лисперов :) Я вот ML знаю по стольку, по скольку, плюс знание Пролога для Qi ещё бы не мешало... ;)

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

Ну или ты мне объясни на пальцах или кинь ссылку с примером, где надо возвращать 2 типа из одной функции.

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

> Если это технически возможно, это обязательно кто-нибудь попробует. И врата ада разверзнутся

Ну, в общем, в Смолтоке почти все реализации так и делают.

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

> Ну почему же, там есть 15 минут и для лисперов :)

Ты еще скажи, что там есть 15 минут для первокласников.

> Я вот ML знаю по стольку, по скольку, плюс знание Пролога для Qi ещё бы не мешало... ;)

Ну пролог такой мелкий язычишко, который стыдно не знать.

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

> Ну пролог такой мелкий язычишко, который стыдно не знать.

У меня детство в обнимку с ассемблером прошло. Я на Си-то очень долго переходил, всё ужасался, какой сложный язык и такой плохой машинный код генерит ;)

mv ★★★★★
()

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

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

> У меня детство в обнимку с ассемблером прошло. Я на Си-то очень долго переходил, всё ужасался, какой сложный язык и такой плохой машинный код генерит ;)

А ты уверен, что щас сможешь написать прогу, работающию хотя бы так же быстро, как gcc-шный код под х86? (речь конечно, не идет об ММХ/SSE-специфичных фенечках)

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

Любая вменяемая крупная программа/среда/платформа состоит из объектов. И это естественно, заворачивать эти объекты в некую систему.
Разумеется, у некоторых индивидуумов, привыкших к языкам, в которых кроме кучи сраных байтов ничего нет, может быть и другое мнение на этот счет, но оно мало интереса представляет.

А проблема?
Ну вот пример:

(make-instance 'standard-class
               :name 'my-class
               :direct-slots '((:name some-slot :initform t
                                :initargs (:some-slot) 
                                :readers (some-slot)))
               :direct-superclasses 
                       (list (find-class 'standard-object)))

И как это на статике? Аргументы _вычисляются_
Учитывая, что ооп в хаскеле нету, а весь полиморфизм статичный?
Как-то никак.
>. Поэтому программировать лучше всего на лучшем в мире императивном языке. То есть, хаскеле.
Довольно бородатый и унылый баян.

guest-3484-2009
()
Ответ на: комментарий от mv

> Я вот ML знаю по стольку, по скольку, плюс знание Пролога для Qi ещё бы не мешало... ;)

Прологовский подход мне кажется весьма подходящим для верификации типов данных. Так что посмотрим, как это сделано в Qi...

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

>Это как-то мешает без малейших сомнений заюзать строку как число (получив мусор, естественно)?

Если опишешь отдельный словарь строк и стек строк - то да, смешать строки с числами уже никак не сможешь. Если специально для этого инструментов не предусмотришь :)

KRoN73 ★★★★★
()
Ответ на: комментарий от guest-3484-2009

> Любая вменяемая крупная программа/среда/платформа состоит из объектов. И это естественно, заворачивать эти объекты в некую систему.

Угу, только слово "объект" здесь не по делу. Точно также можно говорить "структура" или ещё что-то. ООП здесь ни при чём.

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

Это не ко мне, это к фортерам.

> Учитывая, что ооп в хаскеле нету, а весь полиморфизм статичный?

Что значит "нету"? Искаропки - нету, но МП в Хаскеле (правда, не в Haskell98) такое, что объектная система достаточно просто делается, причём не одна. См., опять-таки, Киселёвский код. Правда, никто не пользуется, ибо нафиг не надо.

Что значит "статичный"? С приходом existential types стало возможным вычислять конкретный тип в рантайме (сохраняя при этом все преимущества статической типизации).

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

> Если опишешь отдельный словарь строк и стек строк - то да, смешать строки с числами уже никак не сможешь.

Это почему же? Или ты имеешь в виду "переписать весь стандартный словарь"? Извини, на статическую типизацию не тянет.

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

> А ты уверен, что щас сможешь написать прогу, работающию хотя бы так же быстро, как gcc-шный код под х86? (речь конечно, не идет об ММХ/SSE-специфичных фенечках)

Ну, gcc часто переклинивает. Например, в 4.1.x половину регистров на x86-64 вдруг перестал использовать. Так что, вполне возможно, что без напрягов напишу быстрее. С появлением SSA-прослойки в 4.4 это будет гораздо труднее, конечно ;)

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

> Мне лень писать полный пример
Обидел ни за что.

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

Пишу последнее:
генерация кода в рантайме в жизни была нужна, есть нужна и будет нужна всегда.
Примеры:
- регекспы
- планы SQL запросов
- jit (хотя этот пример - несколько искусственный)
- языки "макросов" в общечеловеческом смысле для пользователя
- операционная система. Чтобы запустить конкретную программу на С, данную в исходном тексте, как правило, не нужно перезапускать операционную систему. Значит, операционная система в целом, если абстрагироваться от понятия файла, является динамической средой исполнения.
- всё, что связано с partial evaluation. Часть вычислений может происходит в статике, часть - в динамике. Если динамичная часть кода выполняется достаточно много раз, то оптимальным представлением для неё является машинный код.
Во всех этих случаях, без машкода обойтись можно, но качество будет ниже. Это будет переход к интерпретированному коду, а это многие не любят (и я тоже не люблю).

Лисп замечателен тем, что в нём есть функция compile, которая представляет из себя примитив для встраивания нового машинного кода в уже запущенный образ без остановки этого образа. Хотя лисп не уникален в этом - можно загрузить .so/.dll/.class, и даже запустить внешнюю прогу через пайп, но всё это не столь элегантно.

В общем, это касается не "динамической типизации", а именно "динамических языков".

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

Засим раскланиваюсь.

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

> > Какие могут быть вообще сравнения haskell с C++, если в последнем нельзя написать 2 функции с 1 сигнатурой но разными возвращаемыми значениями?

> Не понял, зачем это нужно? На пальцах объясни, или дай ссылку.

> До недавнего времени нельзы было иметь const T1 f(T2) одновременно с 
> T1 f(T2) -- это конечно неприятно (как стало в С++0х -- не знаю).

С const - хрен с ним. Это меня мало интересует (тем более это имеет смысл при только возврате
константных/неконстантных ссылок - это поддерживается текущим стандартом C++).

Больше интересует _нормальная_ параметризация.

Я могу написать
    template <class T> void f(const T &);
, но не могу
    template <class T> T f(void);
хотя казалось бы - причем здесь наследие C ? :]

Использовать это можно - и используется в более других языках.
Оно ж понятнее, чем
    template <class T> T f(T unused_shit_here_);

Пример на haskell: вызов полиморфной по возвращаемому параметру функции.

Prelude Data.Word> (maxBound, maxBound, maxBound) :: (Word8, Word16, Word32)
(255,65535,4294967295)

Посмотрите как "изящно" решают это во внутренностях STL:
* вводя во всякие *_traits целочисленные константы. А чтобы всунуть float или более сложную константу
(хотя-бы, чтобы сымитировать maxBound для non-integral типов) начинается веселье:
* раздувая прототип функции добавляя туда фиктивный полиморфный параметр

После таких "штучек" написанный код можно использовать только в рамках нагороженных костылей
(потому, что мало кто читает умные книжки :] и потому, что они решают проблемы C++, а не поставленную задачу).
Мало того - оно потом хрен везде компилится, но это уже совсем другая история :]

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

А потом осильте RWH: http://book.realworldhaskell.org/read/ , чтобы не писать впредь про "испорченность функциональной парадигмой" :]

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

> генерация кода в рантайме в жизни была нужна, есть нужна и будет нужна всегда.

Конечно, этим и сильны функциональные языки.

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

>> генерация кода в рантайме в жизни была нужна, есть нужна и будет нужна всегда.

> Конечно, этим и сильны функциональные языки.

А при чём здесь функциональность? o_O

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

> Больше интересует _нормальная_ параметризация. Я могу написать template <class T> void f(const T &); но не могу template <class T> T f(void); хотя казалось бы - причем здесь наследие C ?

Ты так и не объяснил 2 вещи:

1. зачем такое надо?

2. как компилятор будет вычислять (выводить) Т?

> Посмотрите как "изящно" решают это во внутренностях STL: * вводя во всякие *_traits целочисленные константы.

Разве *это*? Где пример? (по-моему совсем не это!)

З.Ы. А я-то надеялся что-то новое услышать...

З.Ы.Ы. А я нигде не говорил, что STL изящна, скорее наоборот

_____________________________________

Жду нормальный пример.

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

> А чтобы всунуть float или более сложную константу (хотя-бы, чтобы сымитировать maxBound для non-integral типов) начинается веселье: * раздувая прототип функции добавляя туда фиктивный полиморфный параметр

Так это типично функциональный дибилизм^W прием -- вместо заведения локальной *изменяемой* переменной раздуть прототип функции :-) (да, а потом требовать tail recursion elimination, гы-гы-гы)

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

> А при чём здесь функциональность?

А при том. Или что имелось в виду под "рантайм-генерацией кода"? Кроме лямбда-функций ничего в голову не приходит.

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

> Так это типично функциональный дибилизм^W прием -- вместо заведения локальной *изменяемой* переменной раздуть прототип функции :-) (да, а потом требовать tail recursion elimination, гы-гы-гы)

Нормальные люди оборачивают это в монаду State и живут припеваючи.

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

> > А чтобы всунуть float или более сложную константу (хотя-бы, чтобы сымитировать maxBound для non-integral типов) начинается веселье: * раздувая прототип функции добавляя туда фиктивный полиморфный параметр

> Так это типично функциональный дибилизм^W прием -- вместо заведения локальной *изменяемой* переменной раздуть прототип функции :-) (да, а потом требовать tail recursion elimination, гы-гы-гы)

Причем тут рекурсия? Это ж статика шаблоннаю :] Откуда тут вообще рантайм? И элиминировать там нихера не надо - абы вычислилось.
А вообще в g++ уровень вложенности инстанцирования - пицот (500).

Но рекурсивная статика - это тоже весело.

Обычный вызов обычной статической полиморфной функции.

float maxBound();
int maxBound();

template <class T> half_of_max() {
    return (T)maxBound() / 2;
}

double a = (float)half_of_max();

Хреновый пример? Напишите работающий - и вы увидите как "красив" C++.
Если мало будет - могу ткнуть в "красавцев" из STL.

Про раздувание и дЕбилизм - ниасилил. Хочется переменной в haskell - заюзайте State. Она действительно простая, очень простая.

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

> А при том. Или что имелось в виду под "рантайм-генерацией кода"? Кроме лямбда-функций ничего в голову не приходит.

OMG! Лямбды-то каким боком к рантаймной генерации кода относятся? :)

В лисповой программе можно взять текст (функции), откомпилировать его, встроить машинный код в этот же образ (адресное пространство) и тут же вызвать. Это называется рантаймной генерацией кода. Я уже не знаю, как это проще объяснить.

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

Рантайм генерация это, очевидно, через eval и compile.

(defun generate-and-compile-function (name args-list &rest body)
   (eval `(defun ,name ,args-list ,@body))
   (compile name)
   (symbol-function name))

Ну, впрочем в хаскеле и во время компиляции особо не нагенерируешь. (да да, плюсоподобные шаблоны в template haskell это совершеннейшая фигня, особенно в сравнении с макросами CL)

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

>Ну, впрочем в хаскеле и во время компиляции особо не нагенерируешь. (да да, плюсоподобные шаблоны в template haskell это совершеннейшая фигня, особенно в сравнении с макросами CL)

а можно аргументировать?

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

шаблоны принимают информацию о типах и подставляют свое тело в соответствующие места в код.
макросы в лиспе принимают ast и обладают всеми возможностями языка во время компиляции.
Достаточно?

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

>Достаточно?

нет. шаблоны template haskell принимают хаскелевский ast, и обладают всеми возможностями языка во время компиляции (включая IO). можно конкретных примеров - что можно сделать макрами CL и нельзя шаблонами TH?

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

И что, даже монадой state, или как там ее?

"Все возможности", это, понимаете ли, _все_возможности_

В лиспе вся макро-система построена на одном, фактически, операторе
(eval-when ...)
который нетрудно догадаться что делает.

А это ваше:
судя, например, по этому:
http://www.haskell.org/th/
>You can only splice in lists of declarations and expressions, not types, patterns etc.

хреновенькая там обработка ast(еще бы, с таким синтаксисом то)
>You cannot use functions defined in the current module to build splices.

и даже функции из текущего модуля нельзя использовать?
># The Template Haskell datastructures don't yet support all of the extensions GHC provides.

Ну то есть, это m4 поверх интерпретатора хаскеля, встроенный в GHC?
Кривые костыли, короче говоря, а не макросы.

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

Но, конкретный пример - макросы лиспа могут оставлять после себя не только ast, но и данные.

(defmacro get-data (make-array 1000000 :element-type '(unsigned-byte 32) :initial-element 1234567890))

(defvar vec (data))

если код находится в файле, мы получим вкомпилированный в файл массив.

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

> И что, даже монадой state, или как там ее?
Да. Хоть .tar.gz качайте.

> "Все возможности", это, понимаете ли, _все_возможности_

> В лиспе вся макро-система построена на одном, фактически, операторе

(eval-when ...)
> который нетрудно догадаться что делает.

То же самое и здесь - oxford bracket [| тут евалящийся код |].

> А это ваше:

> судя, например, по этому:

> http://www.haskell.org/th/

> >You can only splice in lists of declarations and expressions, not > types, patterns etc.

> хреновенькая там обработка ast(еще бы, с таким синтаксисом то)

> >You cannot use functions defined in the current module to build splices.

> и даже функции из текущего модуля нельзя использовать?


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

> ># The Template Haskell datastructures don't yet support all of the extensions GHC provides.

> Ну то есть, это m4 поверх интерпретатора хаскеля, встроенный в GHC?

> Кривые костыли, короче говоря, а не макросы.


all the _extensions_
Это _нормальный_ интерпретатор/компилятор haskell (не препроцессор) с рекурсией, State и пр. пургой.

sf ★★★
()
Ответ на: комментарий от guest-3484-2009

> если код находится в файле, мы получим вкомпилированный в файл массив.

http://www.haskell.org/haskellwiki/Prime_numbers#Bitwise_prime_sieve

1 в 1 то же самое: в print суется вкомпилированный массив.

Убирая $() и [| |] получаем рантайм версию.

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

>То же самое и здесь - oxford bracket [| тут евалящийся код |].
Не то же. Он один раз раскрывается тут, при компиляции. Это quasiquote.
А eval-when - всегда в выбранных случаях, при загрузке, компиляции или вычислении.
>Довольно весело в декларативном языке компилировать еще неготовый исходник.

>all the _extensions_

Ну вот. Только не надо про "декларативный язык".
Макро-система в отрыве от рантайма это m4. А в хаскеле отрыв имеет место быть.
В лиспе аналог - читаем файл read-ом, на некоторые места натравливаем eval, итог переписываем в тот же файл(и то, возможностей больше будет, чем в th). Это не макросы.

guest-3484-2009
()

Но что-то я суть потерял. Оно, насколько я понял, не может пользоваться для создания синтаксических абстракций. Обработка ast никакая; видимо потому, что хаскелевский синтаксис обрабатывать не легче плюсовского. А какая радость переводить хаскелокод в другой хаскелокод? Ну на то и template, а не meta(или macro или как то так)

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

>Оно, насколько я понял, не может пользоваться для создания 
синтаксических абстракций

http://haskell.org/haskellwiki/Quasiquotation
http://www.rsdn.ru/forum/message/3289552.1.aspx

и в чём здесь проблема создания синтаксических абстракций?

jtootf ★★★★★
()
Ответ на: комментарий от guest-3484-2009

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

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

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

> у так можно, наконец, пример, в котором это преимущество будет очевидным?

Создать класс в рантайме. С именами полей, введенными пользователем.

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

>Создать класс в рантайме. С именами полей, введенными пользователем.

о, вот это уже интересней. а зачем это может быть нужно?

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

> а зачем это может быть нужно?

Для понтов %)

Ну теоретически можно сделать какую-нибудь расширяемую систему при помощи этой фишки. Хотя стоит ли оно того - ХЗ. ИМХО, compile-time макросы - это Ъ, остальное ненужно.

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

> о, вот это уже интересней. а зачем это может быть нужно?

Самомодифицирующийся код, транслирующийся в HDL и прошивающийся в ПЛИС. Терминатор как по-твоему работать должен?

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

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

в лиспе я делаю так:

(eval-when (:compile-toplevel :load-toplevel :execute)
(generate-information (get-spec-from-somewhere somewhere)))

аналог?

Есть ли macroexpand?
Судя по всему нету. Ну, впрочем, что можно от препроцессора ожидать.

guest-3484-2009
()
Ответ на: комментарий от mv

> Самомодифицирующийся код, транслирующийся в HDL и прошивающийся в ПЛИС. Терминатор как по-твоему работать должен?

Убей лиспера - спаси будущее :D

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

> о, вот это уже интересней. а зачем это может быть нужно?

Сходу что в голову приходит - в лисповых ОО СУБД можно в рантайме поменять определение класса, и все готовые объекты лениво поменяются под новое определение. Вот тут, подозреваю, это во всю используется: http://franz.com/products/allegrocache/

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