LINUX.ORG.RU

Сообщения den73

 

gdb и conditional breakpoints

Форум — Development

Думаю, что выражения в conditional breakpoints интерпретируются. Где мне это точно выяснить? Мне нужна ссылка для научной статьи.

 

den73
()

Разработчик Common Lisp удалённо, 200+ руб

Форум — Job

 

den73
()

как жив Nemerle?

Форум — Development

И как связаться с автором? Последний коммит 2 дня назад, но что в целом?

 

den73
()

алгебраический тип данных - это struct?

Форум — Development

Смотрю в википедию, отличий не нахожу. Если так, то почему в википедии не упомянуты Си и Common Lisp?

 

den73
()

зачем нужны примеси, если есть множественное наследование?

Форум — Development

Я встретил такое мнение (см. табличку в конце) : в Скале пытались уйти от проблемы ромба примесями, но примеси сами по себе могут образовывать ромб, поэтому ромб примесей в Скале административно запрещён. Выглядит, как будто сначала плохо подумали, а потом поставили заплату. Или я что-то не понял в жизни?

Иными словами, тогда зачем вообще примеси? Множественное наследование и композиция. Запрети ромб в множественном наследовании и получишь всё, что могут примеси, не вводя их отдельно. Пусть будут просто классами.

 , ,

den73
()

Хаскель - несколько определений одной функции - порядок применения

Форум — Development

Вот программка на Хаскеле

sayMe :: (Integral a) => a -> String

sayMe x
    | x <= 2 = "Less then three!"

sayMe 1 = "One!"

main = putStrLn (sayMe 1)
-- результат  зависит от порядка определений
Здесь печатает «Less then three». Если поменять определения местами, то напечатается «One!». В явном виде я нигде не прочитал, но похоже, что определения обрабатываются по порядку, и первое подходящее применяется.

Эта штука мне нравится, поскольку по сути это тот «полиморфизм», который гениально прост и при этом не налагает никаких требований на систему типов. В С++ или в CLOS методы выбираются не по порядку определения, а по отношению «предок-потомок», или, иными словами «тип-подтип». Это отношение не всегда легко определить.

Но у меня вопросы:

1. Могу ли я размазать определение sayMe по нескольким модулям, ничего не знающим друг про друга?

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

3. Есть ли способ воткнуть своё определение перед первым определением, задав свой частный случай?

 , ,

den73
()

Давайте поговорим о трейтах

Форум — Development

Вот я смотрю очередной раз на трейты. Первоистчник говорит:

Traits do not specify any state variables, and the methods provided by traits never directly access state variables.

Далее смотрим первую попавшуюся статью по PHP и видим:

trait Id
{
    protected $id;
    public function getId()
    {
        return $this->id;
    }
}

Т.е., в PHP трейты - это не трейты, я верно понял?

И теперь вот что я хотел узнать - как соотносятся по производительности трейты с одиночным наследованием реализации. Тут я слегка упираюсь в то, что я не понимаю, как реализованы вирт. ф-ии в С++ при множественном наследовании. Как я понял, если класс Child наследует от Parent1 и Parent2, и мы хотим вызвать виртуальный метод Parent1::Method, то мы должны где-то найти указатель на этот метод. Метод ищется в VMT и Child содержит 2 VMT, для каждого из Parent.

И получается, чтобы найти этот VMT, нам нужно сначала вызвать некую ф-ю VMTOffsetOfParent1(Child). Эта функция может вызываться для всех потомков Parent1, и может принимать на вход только какое-то число, идентификатор класса, а возвращать она должна указатель. Такое отображение можно реализовать только с помощью хеш-таблицы, b-дерева или иного объекта с логарифмическим временем доступа по отношению к количеству потомков Parent1.

По сравнению с этим, при одиночном наследовании вызов вирт.метода осуществляется за линейное время.

Если Parent1 и Parent2 становятся трейтами, то опять же нам нужно вызвать функцию GetParent(Child), которая опять же требует хеш-таблицы для своей реализации, со временем доступа, логарифмическим по отношению к количеству классов, воплощающих этот трейт.

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

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

Верно я мыслю или нет? В свете этого, верно ли, с точки зрения производительности, решение отказаться от наследования реализации, принятое в Rust и Golang?

А зачем мне это нужно: нужно быстро придумать, как реализовать ООП в Яре. Понятно, что нужно включить минимум для начала (потому что версия только 0.4). Но любой минимум потом оказывается более, чем минимальным, и включив что-то в язык, потом уже не избавишься. Поэтому тэг «Яр» здесь должен стоять, уж извините. Он особенно хорош тем, что те, кому я надоел, ставят этот тег в список игнорируемых.

 , , , ,

den73
()

проекту Яр скоро будет 8 лет (как минимум)

Форум — Talks

Гуглил «декларация pure», и вот нашёл

Хех, тогда не было ещё Rust, и то, что сейчас в Rust, мне цитировали из Cyclone. Не было golang, julia. clang находился в зачаточном состоянии.

Что ж, теперь у меня есть и драфт описания, и прототип компилятора, и IDE. Вообще, наверное, жаль, что я не занялся этим вопросом своевременно, с каждым годом становится всё больше разных языков, и я тоже становлюсь всё старее, тупее и ленивее. Но ничего, есть ещё порох в пороховницах и Бог с неба тоже помогает немного :)

Но надо сказать, что пункты 1,3,6 и 8 выпали. Некоторые просто пока ждут своей очереди, а на некоторые нет сил.

Перемещено tailgunner из development

 ,

den73
()

собираемся портировать компилятор Си на Common Lisp

Форум — Development

Мы с Монком начали портировать portable C compiler на Common Lisp. Получится тот же самый компилятор, но написанный на лиспе. Есть желающие подобровольничать? Репозиторий здесь

 , ,

den73
()

Где ещё есть print/read как в Common Lisp с *print-readably* ?

Форум — Development

Вот смотрю Julia

Julia:

julia> Int8[[1 2] [3 4]]
1×4 Array{Int8,2}:
 1  2  3  4
Это круто, конечно, но ведь я уже не зачитаю то, что напечаталось.

Смотрю Dylan: вроде есть что-то похожее на лисповый reader.

Смотрю Io: вроде есть что-то http://iolanguage.org/reference/index.html

  Io> Object clone do(x:=1) serialized
  ==> Object clone do(
  	x := 1
  )

Однако неясно, есть ли что-то подобное *print-readably* Соответственно, вопрос всем: где оно есть, где лично вы им пользовались?

 ,

den73
()

Самый лучший pattern matching где взять?

Форум — Development

Вопрос по дизайну языка. В CL есть destructuring-bind, но он что-то слабоват. Либо ты попал в один шаблон, либо ошибка - никакого destructuring-case нет. Кроме того, квазицитаты, которые тут просятся, использовать нельзя. По сути задействован синтаксис из определения функции, т.е. можно обязательные, необязательные, параметры ключи и сопоставление головы и хвоста списка из консов.

Когда пытаешься использовать pattern matching, сразу становится ясно, что этого мало. Нужно:

1. Нужна возможность сопоставления с несколькими шаблонами, как в case.

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

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

4. Иногда нужно использовать разные предикаты для сопоставления. Т.е. если мы ищем шаблон со строкой «abc», то иногда нам нужно искать без учёта регистра.

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

Я попробовал пару библиотек pattern-matching для CL, но в итоге как-то стал без него обходиться (почему-то это не сильно меня опечалило).

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

 , , ,

den73
()

data breakpoint для Common Lisp (прототип)

Форум — Development

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

CL, конечно же, всем прекрасен. Но для Си такая технология есть, а для CL её нет. Во всяком случае, её нет в Lispworks, SBCL и CCL. Отсутствие этой технологии является большим упущением в конкурентной борьбе, потому что эта возможность нужна (и не нужно это оспаривать).

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

вот такой вариант

Есть добровольцы доделать? Нужно вот что:

1. Отлавливать движение объекта при сборке мусора и переставлять брекпойнт, в чём отчасти поможет *after-gc-hooks*

2. Отключать брекпойнт на время сборки мусора.

Считайте пп 1-2 головоломкой - я думаю, что она имеет решение.

3. Другие места, а не только aref для строки

 ,

den73
()

есть ли книжка по обучению программированию?

Форум — Development

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

Есть ли хоть одна (на родном языке), где излагается, как собственно, устроено ремесло программиста? Меня интересует:

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

 , ,

den73
()

Запрет на вызов функций функций, определённых ниже по тексту - за и против

Форум — Development

Я быстренько глянул. На Си давно не писал, там вроде нельзя. В Лиспе можно, в Яве можно. В Паскале (Дельфи) вроде нельзя. В tcl можно.

Понятно, что для очень многих синтаксисов (может быть, и для Си тоже) технически легко разрешить обращаться к функциям, определённым ниже по тексту. Но я вижу одно мощное «за» запрет такого обращения - проще сделать хорошую поддержку IDE. Обычно в процессе редактирования текст до положения курсора - корректный, а ниже - сломанный. И, допустим, мы хотим в лексически корректном тексте выделить цветом ошибочные обращения к функциям. Если мы обязаны декларировать «forward reference», с этим нет проблем. Если не обязаны, то как только мы сломали текст в текущей позиции курсора, все функции, определённые ниже, строго говоря, исчезли и их больше нет. Поэтому мы не можем ничего проверить, пока текст снова всего файла снова не станет правильным. И так оно будет мелькать от каждой буквы. Дальше мы начнём кешировать, выдумывать таймауты и т.п. Но это всё как-то гнилостно.

Для собственно разработки мне кажется менее удобным требовать определения заранее. Красивая мода начинать с функции main и дальше вниз её детализировать. И не нужно повтора текста. Можно просто писать код и не отвлекаться на декларирование.

Приведите, пожалуйста, свои «за» и «против» необходимости декларировать ф-ии, к-рые будут использованы до места определения.

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

 ,

den73
()

Остались ли ещё в России пользователи Common Lisp?

Форум — Development

У меня складывается ощущение, что нет. Я прав?

Допустим, те, кто в настоящее время продолжает коммитить в open-source проекты. Или пилит что-то своё открытое/закрытое?

Есть "http://ystok.ru/", они в 16-м году выпустили версию своей софтины. Есть Стас Букарёв, я думаю, что он работает где-нибудь в гугле за зарплату, хотя кто знает?

Есть мы, конечно.

А ещё кто-нибудь есть?

Мне кажется, тема совсем обезлюдела.

Отзовитесь, ау!

 

den73
()

как же написать этот парсер?

Форум — Development

Мы предприняли титанические усилия и реализовали интерпретатор Common Lisp (ну, почти всего), способный в любой момент приостановить своё выполнение и вернуть состояние. Состояние можно скопировать и потом перезапустить несколько раз. При этом мы умеем что-то делать и с биндингами специальных переменных. Чтобы копировать состояния эффективно, мы начали делать «версионное состояние», которое копируется более дёшево, чем просто глубокая копия графа объектов. Его, правда, пока не используем, но планируем.

Ничего, что вся эта конструкция тормозная и привязана к SBCL. На этой основе реализована раскраска Яра (пока старой версии, но не суть).

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

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

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

И наш рекурсивно-спускающийся парсер не подходит для этого, потому что как кажется, подсказки можно построить (насколько я понимаю) только на основе формального описания грамматики.

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

При этом понятно, что список ожидаемого, вообще говоря, строится динамически. Например (для лиспа), если написали (defsystem :foo (, то дальше нужно откуда-то взять список всевозможных кляуз для defsystem и предложить именно их. Это не входит в грамматику языка, а входит в метаданные. Т.е. статически сгенерировать сам список продолжений невозможно.

 , , , ,

den73
()

Текст на каком языке программирования наиболее красив визуально?

Форум — Talks

Пишите не ваш любимый язык, а именно ответьте на вопрос. Например, мне нравятся лисп и паскаль, но мне кажется, что текст на Си визуально наиболее красив - очень уж красивы эти фигурные скобочки.

Мнение анонимусов не учитывается.

Перемещено tailgunner из development

 , ,

den73
()

Яр - очередное сочинение на тему синтаксиса

Форум — Development

 

den73
()

Ключи, записи с атрибутами и как всё это получше сделать

Форум — Development

Упёрся. Есть такая простая вещь, как синтаксис.

Вот примеры:

ключ используется сам по себе, без значения
ls -l *.c

в лиспе ключ почти всегда используется в паре со значением
(make-foo :a 1 :b 2) 

<img src="siski.png" alt="UML-диаграмма">

Но ведь есть и «синтаксис»

for i in a do 
Во всех примерах есть общность в том, что есть имена атрибутов и их значения, которые иногда есть, а иногда их нет. Их же можно назвать «ключевыми словами». Хотелось обобщить это так, чтобы было легко и приятно.

И сталкиваемся со следующими противоречиями: Если мы помечаем имя, то запись становится длиннее. Если мы не помечаем имя, то возможно возникновение неоднозначностей.

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

В языках типа С всё понятно - синтаксис там маленький и фиксированный. Все ключевые слова зарезервированы и не могут быть перепутаны с идентификаторами.

В языках с гомоиконностью, или просто в расширяемых языках так не получается. Сегодня я завёл переменную finally, а завтра в языке появилось ключевое слово finally и вот мы приехали.

В лиспе традиционно используются кейворды, например

(defsystem 
  :serial t
  :description "Some utilities by Budden, mostly public domain"
  :depends-on 
  (:alexandria :cl-fad :split-sequence :cl-utilities :named-readtables
   :cl-ppcre		
   :iterate-keywords :swank :decorate-function :closer-mop)
  )

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

(defsystem 
  serial t
  description "Some utilities by Budden, mostly public domain"
  depends-on 
  (alexandria cl-fad split-sequence cl-utilities named-readtables
   cl-ppcre		
   iterate-keywords swank decorate-function closer-mop)
  )
И стало меньше мусора в тексте. Вот. Тут надо принять стратегическое решение, которое потом вряд ли удастся исправить. Посоветуйте что-нибудь.

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

Что для литералов структур (т.е. для записей вида «имя=значение, имя=значение» я налагаю требование, чтобы на каждой строке располагался или один элемент (имя или длинное значение) или целое число пар:

объект хрень
 имя1 
  очень-длинное-значение-1
 имя2 значение2 
 имя3 значение3 имя4 // здесь нас подстрахует парсер
 имя5 значение 5 // несмотря на эту вторую ошибку
кно

 , ,

den73
()

Есть ли в CL и C алгебраические типы данных?

Форум — Development

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

Ну так и что? В С объявляем юнион из структур с тегом. В лиспе - несколько структур и or.

Конструкторы и сопоставление с образцом - это уже лирика (утилиты, так скажем). Верно я понимаю определение АТД или нет?

 , ,

den73
()

RSS подписка на новые темы