Семинар по языкам программирования и компиляторам

Напоминаю, что завтра в 16:00 в ауд. 211 состоится очередное заседание семинара, на повестке два доклада-окончания:

  • «Визиторы в Roslyn», А.С. Захаренко.

  • «Функциональный взгляд на визиторы. Продолжение: менее функциональный взгляд», А.М. Пеленицын.

2 лайка

Сегодняшняя презентация к моему мини-докладу.

2016-04-29-functional-visitors-2.pdf (160,1 КБ)

А ещё мне сегодня сказали, как я понял, что Схема/Рэкет и Кложура это никакие не Лиспы. В качестве антипрува привожу мою любимую Википедию: Lisp: Major Dialects.

1 лайк

Презентация доклада по визиторам PascalABC.NET и Roslyn: Визиторы в PascalABC.NET и Roslyn.pdf (715,2 КБ)

1 лайк

Следующий доклад на семинаре планируется 13 мая, 16:00:

Радько В. Визиторы в Clojure с помощью зипперов

В основном по мотивам статьи, опубликованной выше в этой теме.

1 лайк

Здравствуйте, здесь я хотел бы добавить то, что упустил в своем докладе. Во-первых это “подмена понятий” и вторая функция eval-concat:

(defn eval-concat [node]
  (if (and (= :concat (node-type node))
            (every? string? (:args node)))
     (string/join (:args node))
     node))

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

(defmulti eval-concat :type)
(defmethod eval-concat :default [node] node)
(defmethod eval-concat :concat [node] 
    (if (and (= :concat (node-type node))
             (every? string? (:args node)))
    (string/join (:args node))
     node))

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

> (defmulti foo dispatch-function-1 dispatch-function-2)

> Exception The syntax defmulti has changed
> Example (defmulti name dispatch-fn)

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

(defmulti foo (fn [x y] (+ x y)))
(defmethod foo 100 [x y] (* x y))

> (foo 50 50)
> 2500

Здесь мультиметод может принимать два аргумента, но и dispatch-fn принимает их тоже. Иначе, если они принимают разное число аргументов, то при любом вызове будет возникать ошибка wrong number of args либо при вычислении dispatch-fn, либо уже при вычислении тела мультиметода.

Отдельно хочу сказать спасибо Артему Михайловичу за предложение сделать этот доклад. Надеюсь, что вышло не совсем плохо. :innocent:

4 лайка

Выступление очень хорошее - спасибо.

Вот - видео семинара: https://youtu.be/D51CUBeZVQM

3 лайка

Ещё поднимался вопрос зачем писать двоеточия у имён. Есть ответ на SO. Без двоеточия это «символ», с двоеточием это «ключевое слово», но разница абсолютно непринципиальная. Резюме такое (выделение моё):

Keywords are generally used as lightweight “constant strings”, e.g. for the keys of a hash-map or the dispatch values of a multimethod.

Symbols are generally used to name variable and functions and it’s less common to manipulate them as objects directly except in macros and such. But there’s nothing stopping you from using a symbol everywhere you use a keyword (if you don’t mind quoting them all the time).

А в эту пятницу семинар планируется?

1 лайк

К сожалению, нет.

Доброго времени суток! Летняя практика занесла меня в область анализа (чужого) кода, и я прошу у вас помощи с инструментом Roslyn. Задача на данный момент примерно такая:

  1. Писать всё надо на С#

  2. Дан файл корректного исходного кода, тоже на С#. В нём описаны несколько классов, внутри которых - статические общедоступные методы. К некоторым из них (в зависимости от имени) мне надо добавить к списку параметров ещё один примерно так: было

    public static int M(double a1, double a2)

, стало

public static int M(double a1, double a2, SomeClass a3)

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

a3.do();

.3. Этот файл (отредактированный) надо подключить к моему, скомпилировать. Мой код должен использовать уже модифицированные методы из чужого файла.

Проблемы на данные момент следующие:

  1. Не могу понять, удастся ли это вообще сделать (особенно третий пункт)
  2. Не смог найти, как создать объект ParameterSyntax. В SyntaxFactory нет метода ParseParameterSyntax, а как по-другому - не знаю.

Прошу любой помощи - от полезных ссылок до дельных советов. Буду очень благодарен! Преподаватели, курирующие практику, к сожалению, помочь не могут :frowning:

var parlist = method.ChildNodes().OfType<ParameterListSyntax>().First();
var newparlist = parlist.AddParameters(SyntaxFactory.Parameter(
                    SyntaxFactory.ParseToken("TaylorTestingEntry tst")));

Вот так работает наполовину. Понятно, что токен - это то, что до пробела, а чтобы было хорошо, надо пользоваться второй перегрузкой… Но там мне всё непонятно - что из пяти аргументов - тип?

public static ParameterSyntax Parameter(
	SyntaxList<AttributeListSyntax> attributeLists,
	SyntaxTokenList modifiers,
	ModifiedIdentifierSyntax identifier,
	SimpleAsClauseSyntax asClause,
	EqualsValueSyntax default
)

Первая проблема решилась очень странным, непонятным мне образом)

var newparlist = 
parlist.AddParameters(SyntaxFactory.Parameter(SyntaxFactory.Identifier("tst")).
WithType(SyntaxFactory.ParseTypeName("TaylorTestingEntry ")));

UPD. Что-то такое получилось. Добавляет аргумент всем методам. Но это уже хорошо)

    var path = "OpaqueFunctions.cs";
    var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(path));
    var rt = tree.GetRoot();
    var newrt = rt;
    var nodes = newrt.DescendantNodes().OfType<MethodDeclarationSyntax>();
    int i = -1;
    while(nodes.Count() > (++i))
    {
          var method = nodes.ElementAt(i);
          var parlist = method.ChildNodes().OfType<ParameterListSyntax>().First();
          var newparlist = parlist.AddParameters(SyntaxFactory.Parameter(SyntaxFactory.Identifier("tst")).WithType(SyntaxFactory.ParseTypeName("TaylorTestingEntry ")));
          var newmethod = method.ReplaceNode(parlist, newparlist);
          newrt = newrt.ReplaceNode(method, newmethod);
          nodes = newrt.DescendantNodes().OfType<MethodDeclarationSyntax>();
     }
    
Console.WriteLine(newrt.GetText());

@ileasile я думаю, надо было сделать меншн @wisestump. Жаль, что у него в презентации (выше) нет почты, конечно.

Здравствуйте. При редактировании кода может помочь Syntax Visualizer. Постройте с его помощью дерево программы, которые хотите получить в итоге (в данном случае с добавленным параметром и вызовом a3.do();) и сравните с деревом исходного кода. Так можно будет увидеть, какие синтаксические узлы надо удалить или как их изменить. Кроме того, там можно посмотреть, где хранится имя метода (чтобы добавлять код не во все, а в конкретные).

По поводу третьего пункта: нужно скомпилировать средствами Roslyn или задача состоит только в изменении исходного кода и сохранении его в файл? Если второе, то может помочь этот пример.

3 лайка

Спасибо Вам за ответ! С SyntaxVisualizer я разобрался, использую, и он действительно помогает. Примерно похоже на DOM + Javascript) Часть проблем я решил, но многие - костыльным образом. Например, заменить комментарий на узел адекватно не получается, приходится писать много кода… На данный момент этот код здесь: https://github.com/qrodochenko/opaque-func-lib/blob/master/Muradyan/TestingSystem/TestingSystem/Program.cs И вот замена комментария - это строчки с 81 по 147. Как сделать короче, не знаю(

Задача стоит в выполнении этих модифицированных функций. Решил использовать Scripting API. Вроде пока получается)

Вообще очень бы Вашей хотелось критики - наверняка многие вещи на C#/ Roslyn можно писать красивее и короче.

Тут, кстати, на 31-м слайде картинки не хватает, кажется. @wisestump

А продолжение вопроса @ileasile — на SO.

Спасибо, исправил: Визиторы в PascalABC.NET и Roslyn.pdf (714,2 КБ).

Внимание!

В этом учебном году начинает работу семинар “Языки программирования и компиляторы”. Первое заседание семинара состоится 19 октября в 15.30.

Докладчик - Малеванный М. “Устойчивый поиск точки привязки в меняющемся коде”

Аудитория - 206.

5 лайков

Аудитория - 206

Маленькая аудитория :frowning:

Внимание!

Второе заседание семинара “Языки программирования и компиляторы” состоится 2 ноября в 15.30.

Докладчик - Волошин Б. “Тематика работ Робилларда, связанная с исследованием программ с помощью Concern Mapperа”.

Для справки: Concern Mapper - это наиболее близкий инструмент к инструменту аспектной разметки кода Миши Малеванного.

Аудитория уточняется.

1 лайк