LINUX.ORG.RU

Homoiconic C

 homoiconicity,


3

2

Я тут упоролся и подумал, а что если бы у нас был ЯП уровня Си с гомоиконным синтаксисом в стиле Io или Julia. То есть — у нас есть интерпретатор гомоиконного языка, который работает как макропроцессор, и результат трансформаций исходного кода скармливается затем компилятору языка с Си-подобной семантикой. И у нас будет нормальный тьюринг-полный макроязык, который позволит бескостыльно расширять возможности ЯП неограниченно. Компилирующаяя же часть будет по сути обычным компилятором Си (просто читающим входные данные в неСишном синтаксисе).

Это ж кайф. Выражения типа regexp(«^[a-z][a-z0-9]») или format(«%s - %s (%d)», bla1, bla2, i) можно будет автоматически обрабатывать макропроцессором и отправлять компилятору оптимизированный вариант. Это значит, регулярка, например, будет скопилирована в конечный автомат при компиляции программы, а не при выполнении.

Вот эта вот странная задачка, на которой dr_jumba проверял лаконичность языков, записывалась бы как-то вот так:

sample_function := fn(a(iterable(T))) to(T) {
    a select(match(regexp(/^J[a-z]+/))) each_chunk(3) map(format_with("~1 and ~2 follow ~3")) join("\n")
}

Дискас.

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

Ну вы же понимаете, что вложенные QQ — это несколько абсурдно.

Абсурдно как раз обратное. Форма квазицитирования - часть языка, если внутри квазицитаты может быть любое выражение, то в том числе и другая квазицитата там тоже может быть.

anonymous
()
Ответ на: комментарий от quasimoto

Ну вот в одном случае вероятность найти до запуска

Мне не надо искать ошибки «до запуска», мне надо искать ошибки в как можно более ранний момент времени. Надо объяснять, что «до запуска» и «как можно раньше» - понятия никак не связанные?

так чтобы это позволяло проектировать завязываясь на и _используя_ эту логичность

Зачем, если это неудобно?

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

Я всегда могу написать терм, в которой слои будут смешиваться. И единственный способ узнать об этом смешивании - запустить над этим термом вычислитель, соответствующий семантике языка, который бросит исключение. Динамика со статикой тут ни чем не отличаются. Что хаскель бросает исключение, если написать 1 + «2», что лисп в (+ 1 «2»). Вы просто почему-то считаете, что тайпчек - это нечто отдельное от исполнения программы. Нет, не отдельное. Тайпчек - это часть исполнения. Запуск тайпчека = старт исполнения программы (запуск того самого вычислителя). Разница только в одном - в статике вычисление типов выполняется до вычисления термов, а в динамике - одновременно. Но и там и там бы получаем ошибку а рантайме. Которую потом можем исправить.

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

Форма квазицитирования - часть языка

Нет. Afaik, это особенность ghc.

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

Осталось только объяснить — зачем, и привести пример, где это необходимо. Ну и можно сделать свой quoter с собственной QQ, в котором есть экранировка |].

dmfd
()
Ответ на: комментарий от quasimoto

Скорее это:

[|, [p|, [t|, [d|

Можно, конечно, для вложенных QQ заставить их возвращать лист AST со строкой, но зачем?

dmfd
()
Ответ на: комментарий от anonymous

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

Какая восхитительная софистика.

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

Запуск тайпчека = старт исполнения программы (запуск того самого вычислителя). Разница только в одном - в статике вычисление типов выполняется до вычисления термов, а в динамике - одновременно.

Технически это неверно. Бесконечное вычисление в статике может пройти проверку типов за конечное время. В динамике это невозможно: мало ли, вдруг у нас какой-нибудь операнд берётся из фабрики, которая возвращает разные типы в зависимости от фазы Луны (не сомневаюсь, что мощь динамики это позволяет).

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

но зачем?

Например.

Вообще, multi-stage системы такое умеют — в MetaML / MetaOCaml можно составлять вложенные brackets и языки на всех уровнях тождественны, по сравнению с ними templates в C++ / Haskell это 2-staged системы. При этом в самом GHC AST цикличен — http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/HsExpr.html (HsExpr -> HsBracket -> HsExpr -> ...), аналогично http://hackage.haskell.org/packages/archive/haskell-src-exts/latest/doc/html/... (Exp -> Bracket -> Exp -> ...), просто http://hackage.haskell.org/packages/archive/template-haskell/latest/doc/html/... не реализует его полностью.

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

2-staged системы

Хотя это не мешает сделать шаблон, делающий шаблон, делающий шаблон, ... непосредственно в Monad Q.

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

А мне показалось что тут одинэсом больше пахнет.

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

Технически это неверно.

Как раз технически это и верно.

Бесконечное вычисление в статике может пройти проверку типов за конечное время.

Какое выражение, в какой системе типов, каким алгоритмом? Ты же понимаешь, что в зависимости от ответов на эти вопросы, твое утверждение перестает быть верным?

anonymous
()
Ответ на: комментарий от dmfd

Нет.

Ну как нет? Тогда и квазицитирования в языке нет.

Afaik, это особенность ghc.

Нет, это везде.

Осталось только объяснить — зачем, и привести пример, где это необходимо.

Чтобы писать macro-generated макросы, без которых макросистема абсолютно бесполезна (и вообще макросистемой не является).

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

Где ты там софистику увидел? Я просто воспользовался логикой апологетов статики. Вы просто такие интересные товарищи - когда вам зеркально возвращаешь ваши же утверждения, начинаете ныть.

anonymous
()
Ответ на: комментарий от quasimoto

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

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

Самое смешное еще то, что в TH при этом нету никакой изоляции состояний. Статикоеубанство во всей красе.

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

Где ты там софистику увидел?

Да там ничего нет, кроме софистики.

Я просто воспользовался логикой апологетов статики.

За софистикой ожидаемо следует демагогия.

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

Мне не надо

неудобно

А мне надо и удобно.

Надо объяснять, что «до запуска» и «как можно раньше» - понятия никак не связанные?

Если говорить про AOT, то «до запуска» всяко раньше чем любое «как можно раньше» которое начнётся только в рантайме (бинарник уже получился, в память загружен и начал выполняться и звонить в библиотеки и ядро).

Но и там и там бы получаем ошибку а рантайме

То есть, на минутку, compile-time уже стал runtimом? Ладно, довод про удобство субъективен, программа начинает работать ещё во время кодирования, потому что IDE может опрашивать тайпчекер, но всё ещё остался довод про распределение вероятностей отклонений от модели по временам от момента запуска — провели статические проверки (не только типы, вообще говоря), — получили вырожденное распределение.

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

А мне надо и удобно.

Ну вы что-то не так делаете.

Если говорить про AOT, то «до запуска» всяко раньше чем любое «как можно раньше» которое начнётся только в рантайме

Ну это неправда.

То есть, на минутку, compile-time уже стал runtimом?

Он им никогда не переставал быть. Семантика никакого статическог о языка никак не регламентирует алгоритм проверки типов и время его исполнения.

Ладно, довод про удобство субъективен, программа начинает работать ещё во время кодирования, потому что IDE может опрашивать тайпчекер

Конечно, может. И при чем тут тайпчекер? ИДЕ может произвольно работать со средой (частью которой является тайпчекер), запускать тесты ф-и во время ее редактирования и т.п.

но всё ещё остался довод про распределение вероятностей отклонений от модели по временам от момента запуска — провели статические проверки (не только типы, вообще говоря), — получили вырожденное распределение.

Вырожденное не получаем, вероятность поймать ошибку всегда меньше единицы, каким бы статическим чекер ни был. Так что тут нужны конкретные вероятности - ну, например, если 0.999 для статического чекера и 0.99 для динамического, то понятно, что обрекать себя на ограниченность статики ради этих 0.009 никакого профита нет.

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

Конкретнее можно?

Можно.

Мне не надо искать ошибки «до запуска»

А мне надо.

Надо объяснять, что «до запуска» и «как можно раньше» - понятия никак не связанные?

Да.

Зачем, если это неудобно?

Кому и почему?

Динамика со статикой тут ни чем не отличаются. Что хаскель бросает исключение, если написать 1 + «2», что лисп в (+ 1 «2»).

Это выглядит если не прямой ложью, то подменой терминов.

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

False

Тайпчек - это часть исполнения.

«Формально верно, по сути - издевательство» (ц)

Запуск тайпчека = старт исполнения программы (запуск того самого вычислителя).

False. Рантайм другой.

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

Да, такая мелочь.

Но и там и там бы получаем ошибку а рантайме. Которую потом можем исправить.

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

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

А мне надо.

Можно узнать зачем? Интересно просто. Зачем откладывать поиск ошибки до тайпчека, если можно сразу запустить тест и пофиксить все?

Это выглядит если не прямой ложью, то подменой терминов.

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

«Формально верно, по сути - издевательство» (ц)

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

False. Рантайм другой.

Что, прошу прощения? Давайте на примерах. Где в STLC рантайм?

Да, такая мелочь.

Ну да. С точки зрения программистов есть код, этот код отдается на вход черному ящику (рантайму), который проверяет типы, выполняет тесты, етц. - и либо возвращает результат работы программы, либо дает ексцепшн с описание ошибки. Какая программисту разница, что и в каком порядке происходит после нажатия кнопочки «выполнить»? Главное, чтобы черный ящик побыстрее выплюнул свой эксцепшн да поточнее указал, в чем дело. Так?

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

можно сразу запустить тест и пофиксить все?

У тебя всегда 100% тестовое покрытие? А тесты выполняются быстрее, чем проходит компиляция?

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

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

Рантайм другой.

Что, прошу прощения? Давайте на примерах.

Пример - в последнем абзаце предыдущего поста.

Главное, чтобы черный ящик побыстрее выплюнул свой эксцепшн да поточнее указал, в чем дело. Так?

Главное - гарантировать отсуствие в программе как можно более широкого класса ошибок и сделать это до ее запуска.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от anonymous

Ну это неправда.

$ $EDITOR <- 1
$ make    <- 2
$ ./a.out <- 3

1 < 2 < 3.

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

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

Так что тут нужны конкретные вероятности - ну, например, если 0.999 для статического чекера и 0.99 для динамического, то понятно, что обрекать себя на ограниченность статики ради этих 0.009 никакого профита нет.

Не, я говорю про распределение — вероятность отойти от модели, то есть поймать ошибку, в первую минуту, в первый час, на сотый запуск программы спустя десять часов. Там сложное распределение обусловленное особенностями работы control flow — для примера допустим, что мы работаем с гетерогенными графами, а хотим чтобы они были «раскрашены» определённым образом (то есть, в такой узел графа я могу положить только такие значения, а в такой — такие, в том же SBCL я видел баги с nil is not integer который ведёт к коду который не пойми как строит сложный граф).

А если программа верифицирована относительно модели, то у нас пик == 1 в нулевой точке и вырожденное распределение.

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

Тогда и квазицитирования в языке нет.

Главное, что сплайс есть. Квазицитирование упрощает построение AST, но само по себе на мощность системы шаблонов никак не влияет.

dmfd
()
Ответ на: комментарий от anonymous

Как раз технически это и верно.

Без обоснований ответ не принимается. Пример бессилия динамики, когда ошибка типов никак не проверяется и пролезает в случайное место рантайма, я привёл.

dmfd
()
Ответ на: комментарий от quasimoto

Там какой-то синтетический пример.

multi-stage системы такое умеют

Кроме как ради чувства завершённости языка это что-нибудь даёт? Хотя лучше не спрашивать. Боюсь, пытаясь разобрать пример n-кратного шаблона, я упаду в swap.

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

Кроме как ради чувства завершённости языка это что-нибудь даёт?

Если кому-то нужно генерировать top-level код, то нельзя исключать, что кому-то захочется генерировать код генерирующий top-level код :) Хотя я и не знаю зачем это в нужно в хаскеле, в лиспе ещё понятно — там в компиляторах overmacrosed, например.

@anonymous а, кстати, цитаты в цитатах которые не d работают:

if' :: Q Exp -> Q Exp -> Q Exp -> Q Exp
if' p x y = [| if $p then $x else $y |]

plus :: Q Exp -> Q Exp -> Q Exp
plus x y = [| $x + $y |]

test :: Num a => Bool -> a -> a -> a -> a
test p x y z = $(if' [| p |] [| $(plus [| x |] [| y |]) |] [| z |])
quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

и не d в d

genTest :: Lift t => t -> Q [Dec]
genTest z = [d|
    test :: Num a => Bool -> a -> a -> a        
    test p x y = $(if' [| p |] [| $(plus [| x |] [| y |]) |] [| z |])
  |]

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

А тесты выполняются быстрее, чем проходит компиляция?

Ну в общем случае - конечно быстрее.

У тебя всегда 100% тестовое покрытие?

Какое именно покрытие? Они разные бывают, существенно.

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

Это ты про кого?

Пример - в последнем абзаце предыдущего поста.

Можно процитировать? Я ничего похожего на пример там не увидел.

Главное - гарантировать отсуствие в программе как можно более широкого класса ошибок и сделать это до ее запуска.

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

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

Потому что запуск системы может быть дорогим.

Ну вот мы уже куда-то приближаемся. Прелесть динамических систем как раз в том, что их запуск предельно дешев. Собственно, тесты даже можно выполнять on-the-fly, как тайпчек, прямо не прекращая редактирования программы.

anonymous
()
Ответ на: комментарий от quasimoto

1 < 2 < 3.

Так чего ты сравниваешь один ЯП сам с собой? Сравнивать надо разные. Если в ЯП нету тайпчека, то его запуск и прогон тестов легко может оказаться быстрее проверки типов в языке аналогичном, но со статической типизацией.

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

Но в реальности такого не бывает. Никакая система типов тебе не даст гарантий 100%. В сферическом же вакууме тебе и тесты 100% гарантии дадут.

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

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

А если программа верифицирована относительно модели, то у нас пик == 1

Нет, конечно. Тебе никто не гарантирует и гарантировать не может, что программа соответствует модели. Ну и опять повторюсь - соответствие модели это баззворд, это неинтересно. Цена ошибок несоответствия модели пренебрежимо мала. Ценные ошибки - это ошибки самой модели, конкретно - неполноты, противоречивости и некорректности. Кто тебе докажет, что твоя модель _действительно_ решает задачу?

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

anonymous
()
Ответ на: комментарий от dmfd

Главное, что сплайс есть.

Но квазицитирования нет.

на мощность

Мощность - это баззворд. Все тьюринг-полные ЯП одинаково мощны, но толку? Вопрос в юзабельности инструмента. макросистема без квазицитирования и развитого дсл (типа как в scheme) - неюзабельное говно. Потому что при построении АСТ руками сложность написания макросов возрастает на порядки. Это как переход от ассемблера к машине тьюринга.

anonymous
()
Ответ на: комментарий от dmfd

Пример бессилия динамики, когда ошибка типов никак не проверяется и пролезает в случайное место рантайма, я привёл.

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

anonymous
()
Ответ на: комментарий от dmfd

Кроме как ради чувства завершённости языка это что-нибудь даёт?

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

anonymous
()
Ответ на: комментарий от quasimoto

кстати, цитаты в цитатах которые не d работают:

Не увидел примеры цитат в цитате.

Если кому-то нужно генерировать top-level код, то нельзя исключать, что кому-то захочется генерировать код генерирующий top-level код

Не обязательно top-level - еще для локальных определений. В том и проблема TH - нельзя определить макрос внутри локального контекста функции и там же его использовать. И вообще нельзя использовать макрос в одной единице компиляции с определением.

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

Потому что при построении АСТ руками сложность написания макросов возрастает на порядки.

Лисперы вообще всё ручным построением AST делают и ничего.

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

Лисперы вообще всё ручным построением AST делают и ничего.

Разве что общелисперы. В схеме все ок в этом плане.

anonymous
()
Ответ на: комментарий от dmfd

Я почему-то могу.

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

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

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

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

Мы говорим не о применении программы а об ее разработке как раз.

Еще раз - написали код, нажали кнопочку «выполнить», нам плюнуло ошибку. Каким образом определить была она во время тайпчека или исполнения?

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

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

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

Еще раз - написали код, нажали кнопочку «выполнить», нам плюнуло ошибку.

Ещё раз: каким образом нам плюнет ошибку в этом примере:

(defun f (x)
    (if (> (get-internal-real-time) 100000)
        (sin x) "abc"))
(Это первый раз, когда я пишу на лиспе, но вроде всё компилируется и работает до поры.)

dmfd
()
Ответ на: комментарий от anonymous

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

Это ты про кого?

Это я про тебя.

У тебя всегда 100% тестовое покрытие?

Какое именно покрытие?

Используй любое распространенное определение.

Пример - в последнем абзаце предыдущего поста.

Можно процитировать?

Нет, без контекста это бесполезно. См. последний абзац поста Homoiconic C (комментарий)

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

[False]*3

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

Ложки нет, Нео. Нет никакого черного ящика. Компилятор, программа, тесты - есть, а черного ящика - нет.

Потому что запуск системы может быть дорогим.

Ну вот мы уже куда-то приближаемся.

Нет. Судя по вот этому:

Прелесть динамических систем как раз в том, что их запуск предельно дешев

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

тесты даже можно выполнять on-the-fly, как тайпчек, прямо не прекращая редактирования программы.

И здесь вид типизации тоже не причем.

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

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

1. Не означает.

2. А зачем нам знать, что нет ошибок относительно некорректной модели?

В динамическом языке это не означает ровным счётом ничего.

Как и в статическом, да. Получить гарантии невозможно.

anonymous
()
Ответ на: комментарий от dmfd

Ещё раз: каким образом нам плюнет ошибку в этом примере:

Никаким, точно так же как никаким образом тут не плюнет ошибку тайпчекер. Т.к. ошибки типов тут нет.

anonymous
()
Ответ на: комментарий от dmfd

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

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

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

Это я про тебя.

Тогда это утверждение неверно.

Используй любое распространенное определение.

Тогда да, у меня 100% покрытие ф-й/операторов. И я не представляю как можно писать код, в котором оно не 100%. Это получается пишем код, который ни разу не запускается? Бред.

Нет, без контекста это бесполезно. См. последний абзац поста Homoiconic C (комментарий)

Я не вижу там ни слова про STLC.

Ложки нет, Нео. Нет никакого черного ящика. Компилятор, программа, тесты - есть, а черного ящика - нет.

Рантайм с тайпчекером - это и есть черный ящик.

Потому что дороговизна запуска не имеет вообще никакого отношения к типизации.

Имеет и прямое.

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

При чем тут стенд вообще? Все прекрасно запускается и без стенда.

И здесь вид типизации тоже не причем.

Я и не говорил что он здесь при чем.

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

Здесь — может и нет. Ошибка будет там, где значение этой функции будет использовано.

тут не плюнет ошибку тайпчекер

Ерунду говорите.

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