о void

Jun 16, 2009 15:50

Блядские void'ы. Придётся вводить (.net-invoke* ...) для методов, возвращающих void, ибо:

var x = f();является некорректным выражением, если f возвращает void. Ненависть!
Ну вот _зачем_ делать функции, не возвращающие _ничего_? Почему не обойтись возвращением null?? Ну или сделать void полным типом.

lisp, .net, мимолетное, ненависть, профзаметки

Leave a comment

wizzard0 June 16 2009, 13:24:28 UTC
а нельзя вкрутить какой-то синтаксический сахар вроде unit() или другой bottom type под это дело?

Reply

dark_aurel June 16 2009, 14:07:45 UTC
Что ты имеешь в виду? Можно поподробнее?)

Reply

wizzard0 June 16 2009, 14:15:15 UTC
мм..

а можешь подробнее расписать задачу, я тогда буду более уверен (или не уверен =)) в том, что в голову пришло

Reply

dark_aurel June 16 2009, 15:01:20 UTC
Задача заключается в генерации C# кода из S-expressions. Это не конечная цель, это одна из важных вспомогательных задач, т.к. поверх этих S-expressions строятся все-возможные DSL.

Каждая языковая конструкция -- макрос (например, .net-invoke, .net-setq, .net-let, etc). Этот макрос разворачивается в собственно лисповый код, генерирующий соотв. код целевого языка. Лисповый код представляет из себя вывод в поток необходимых выражений + возвращение некого значения.

Большинство конструкций разворачиваются лисповый код, который выводит в выходной поток строки вида: "var = ;" (где xxx -- временная переменная, yyy соотв. конструкция хостового языка) и возвращает xxx.

И всё бы хорошо. НО! для некоторых конструкций (например вызова функции, возвращающей void) такой целевой код некорректен. Кодогенератор сам по себе ничего не знает о прототипах функций. Вот и приходится вводить дополнительную конструкцию .net-invoke*, которая будет разворачиваться в "yyyy();".

Такие дела.

Reply

wizzard0 June 16 2009, 17:03:16 UTC
первое что придумалось

delegate void Func(T arg); // тут надо подумать с арностью, я предпочитаю в таких случаях обходиться кортежами
delegate RT Func(T arg);
class Unit{} // (_|_)

RT Maybe(Func f, T arg){ return f(arg); }
Unit Maybe(Func f, T arg){ f(arg); return new Unit(); }

и генерировать не
var xxx=yyy(...)
а
var xxx=Maybe(yyy, ...)
ну и перегрузкой будет выбираться корректный вариант. вроде такое даже инлайнится.

Reply

wizzard0 June 16 2009, 17:07:22 UTC
ах да, к классу Юнит можно еще прикрутить операторы implicit cast'ов в [], 0, False и т.д.

Но это somewhat dangerous. Использовать по вкусу и в ограниченных пределах =)

Reply


Leave a comment

Up