LINUX.ORG.RU

Сообщения ilammy

 

Как получить правильные размеры workarea в мультимониторной системе?

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

Вроде бы для этого есть свойство _NET_WM_WORKAREA, но туда помещается только один прямоугольник, который чаще всего показывает погоду на Марсе: то bounding box, то странно расширенный прямоугольник главного монитора.

Ещё вариант: пройтись по всем окнам, посмотреть на _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL, рассчитать доступное пространство самому.

Ну и упоротый вариант: создать временные окна, растаскать их по мониторам, максимайзнуть, подождать максимайза (как?), померять размеры.

Я что-то упускаю или это всё, что можно сделать?

 , , ,

ilammy
()

Инициализация константных полей структур

Как вы инициализируете структуры с const-полями, выделяемые в куче?

А то я знаю только один рабочий способ, но он выглядит как-то... неестественно:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

struct foo {
        void *const ptr;
};

int main()
{
        struct foo *bar;

        bar = malloc(sizeof(*bar));

        memcpy(bar, &(struct foo) { bar }, sizeof(*bar));

        printf("%p", bar->ptr);
}

 

ilammy
()

Слежение за изменениями страниц памяти

Существует ли под онтопик аналог MEM_WRITE_WATCH из оффтопика — возможность для процесса узнать, что в страницу памяти была произведена запись? А то единственное юзерспейс-решение, похоже, это mprotect() и слушать SIGSEGV, но обработчик сигнала-то кто угодно может переопределить и пока слушалке.

Я так понял, прямая реализация того, что есть у Винды, нам не светит как минимум до 2020 года (US Patent 6738875). Но по идее можно прицепиться к обработчику #PF вместо вытеснения страниц на диск, обойдя ограничения патента. Не знаю, правда, насколько это будет тормозить.

Или правильные посоны следят за изменениями через шаманство с fork() и copy-on-write?

 , ,

ilammy
()

Коллбеки vs синхронный код

(Речь идёт о Qt4 и C++03.)

Такая ситуация. По нажатию кнопки необходимо выполнить запрос через сеть. Если всё окей, то надо взять полученные от сервера данные и выполнить действие A. Если запрос облажался, то надо показать пользователю сообщение об ошибке и выполнить действие Б. Запросы к сети выполняются сторонним объектом Г, у которого исключительно синхронный блокирующий интерфейс.

Очевидно, что дёргать Г на главном потоке нельзя, так как это заблокирует event loop. Поэтому Г-запросы выполняются в побочном потоке через QRunnable-обёрточку, которая сохраняет результаты и сигналит о их завершении (или факапе).

Есть как минимум два подхода к подобной обработке: асинхронный через коллбек-слоты, которые связываются с сигналами обёрточки и просто вызываются, когда приходит время; и синхронный через QEventLoop, когда сигналы обёрточки связываются с QEventLoop::quit() и пока там Г думает, обработчик нажатия на кнопку крутит локальный event loop.

Какой способ предпочитает использовать лоровец? Есть ли какие-либо технические преимущества у какого-либо из них?

 ,

ilammy
()

gcc странно инициализирует std::vector внутри структурки

(На работе меня игнорируют, так что спрошу здесь.)

Требуются люди со скиллом C++ Standard Interfacing V.

Explain:

$ cat cpp.cpp
#include <vector>

struct A
{
    std::vector<int> v;
};

struct B
{
    B()
#ifdef WITH_INIT
    : a()
#endif
    {}

    A a;
};

int main()
{
    B b;
    b.a.v.push_back(42);
}
$ g++ -O0 -S -o cpp.s.0 cpp.cpp

$ g++ -O0 -S -o cpp.s.1 cpp.cpp -DWITH_INIT

$ diff -u cpp.s.0 cpp.s.1
--- cpp.s.0   2014-08-26 15:42:19.635177434 +0300
+++ cpp.s.1   2014-08-26 15:42:25.295177509 +0300
@@ -80,6 +80,12 @@
    subq   $16, %rsp
    movq   %rdi, -8(%rbp)
    movq   -8(%rbp), %rax
+   movq   $0, (%rax)
+   movq   -8(%rbp), %rax
+   movq   $0, 8(%rax)
+   movq   -8(%rbp), %rax
+   movq   $0, 16(%rax)
+   movq   -8(%rbp), %rax
    movq   %rax, %rdi
    call   _ZN1AC1Ev
    leave 

Мне интересно, это gcc/libstdc++ бажит, или там нечто в стандарте позволяет так делать?

 , , ,

ilammy
()

A Nanopass Framework for Commercial Compiler Development

/cast true_admin; анонимус, толкавший nanopass народу; другой умный анонимус

Мне одному кажется, что оригинальной реализации сабжа от Эндрю Кипа и компании для commercial compiler development недостаёт хоть чего-то для обработки ошибок и реализации макросов?

Для сообщений об ошибках надо писать свой парсер и подпиливать грамматику языка, чтобы прямо в программе сохранять информацию о положении конструкций в исходнике. Для макросов надо вообще городить свои pattern matcher и code walker, потому что всё оригинальное добро на клёвом compile-time syntax-case и — сюрприз! — не позволяет доопределять языки в рантайме.

Итого что в осадке остаётся? Разве что идеи о том, 1) что маленькие специализированные проходы удобнее комбинировать и дорабатывать, чем большие монолитные, 2) что eDSL лучше сраной кодогенерации, 3) что pattern matching удобен для написания трансляторов. Ну, блин, это вроде и так очевидные вещи.

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

В общем, правы были те ребята из ICFP о том, что nanopass годится только как наглядное пособие для обучения. Даже во второй инкарнации. Ну, или как, э-э-э... pattern matcher для бек-энда, если закрыть глаза на обработку ошибок.

Я уж думал, появилось хоть что-то, уменьшающее количество ad-hoc решений при реализации языков. Но, похоже, создание подходящих утилит всё ещё остаётся искусством.

/discuss

 , ,

ilammy
()

Где можно почитать больше про CK-макросы на syntax-rules?

В теоретической информатике есть такая штука как CK-автомат. Помимо написания заумных статей, у него есть и более приземлённое предназначение. Он позволяет записывать call-by-value макросы в Scheme.

Вот, собственно, он:

(define-syntax $
  (syntax-rules (quote)
    (($ e) ($ () e))
    (($ () 'v) v)
    (($ (((! ...) a ...) . s) 'v) ($ s #f (! ... 'v) a ...))
    (($ s #f (! va ...))          (! s va ...))
    (($ s #f (! ...) 'v a ...)    ($ s #f (! ... 'v) a ...))
    (($ s #f (! ...) a aa ...)    ($ (((! ...) aa ...) . s) a))
    (($ s (! a ...))              ($ s #f (!) a ...)) ) )
Вот так пишутся простейшие функции:
(define-syntax $cons
  (syntax-rules (quote)
    ((_ s 'a 'd) ($ s '(a . d)))) )

(define-syntax $map
  (syntax-rules (quote)
    ((_ s 'f '() ...)      ($ s '()))
    ((_ s 'f '(a . d) ...) ($ s ($cons (f 'a ...) ($map 'f 'd ...)))) ) )

(define-syntax $filter
  (syntax-rules (quote)
    ((_ s 'p '())      ($ s '()))
    ((_ s 'p '(a . d)) (p a ($ s ($cons 'a ($filter 'p 'd)))
                            ($ s           ($filter 'p 'd)) )) ) )

(define-syntax $quote
  (syntax-rules (quote)
    ((_ s 'x) ($ s ''x)) ) )
(Я ещё не придумал, как написать нормальный if.) CPS-предикаты для $filter:
(define-syntax ?bool
  (syntax-rules ()
    ((_ #f t f) t)
    ((_ #t t f) t)
    ((_ :: t f) f) ) )

(define-syntax ?symbol
  (syntax-rules ()
    ((_  (a . d) t f) f)
    ((_ #(x ...) t f) f)
    ((_ a-symbol t f)
     (let-syntax
         ((? (syntax-rules ()
               ((_ a-symbol tt ff) tt)
               ((_ else     tt ff) ff) )))
       (? ! t f) )) ) )
И можно делать вот такое:
($ ($quote
     ($map '$cons
       ($filter '?symbol '(a b 1 2))
       ($filter '?bool   '(3 #t #f 4)) ) ))  ===>  '((a . #t) (b . #f))
Так вот, можно ли где-то почитать про практический аспект применения данного макроса? Или это тайные знания Олега Киселёва?

 , ,

ilammy
()

Произвольные классы методов для дженериков

Я опять выхожу на связь, потому что ниасилил AMOP.

Вот допустим у меня есть

(defclass foo () ())
Я могу докинуть немного кода в его инициализацию:
(defmethod initialize-instance ((object foo) &rest initargs)
  (format t "foo instantiated~%")
  (call-next-method) )
Макрос defmethod на самом деле раскрывается во что-то вроде
(let ((gf (ensure-generic-function 'initialize-instance)))
  (add-method gf
    (make-instance
      (generic-function-method-class gf)
      ':specializers (list (find-class 'foo))
      ':lambda-list '(object &rest initargs)
      ... ) ) )
Класс добавляемого метода вытаскивается из самого дженерика. А можно ли добавить в дженерик метод другого класса (естественно, наследника того, что вернёт generic-function-method-class)? А для предопределённых дженериков (того же initialize-instance) так можно делать?

У defmethod какого-то интерфейса для этого нет. Я попробовал вручную вызвать add-method, но SBCL (который я запустил второй раз в жизни) ругается на какую-то фигню, которую я не понимаю (keyword parameter value is not a symbol, или типа того).

 ,

ilammy
()

IDE для R7RS Scheme

Готовый сабж существует? Или появится только когда лично я его напишу?

А то отлаживать с помощью вручную натыкиваемых логов — боль и страдание. Пока пойду изобретать макрос define-traced.

 , ,

ilammy
()

Почему в CLOS только standard-class является экземпляром самого себя?

По метаобъектным системам информацию днём с огнём не сыщешь (что доказывает их нужность :trollface:). Книг тоже меньше, чем три с половиной (или их тоже хрен найдёшь). Да и вообще, складывается такое впечатление, что за пределами Common Lisp к метауровню объектных систем относятся исключительно как «Ух ты, класс класса» — как к забавной, но не глобально продуманной идее. Ими можно пользоваться, чтобы добавить метод-другой, но они не позволяют действительно влиять на объектную систему. Разве что в Руби через призму Гугла и Stack Overflow видится некоторое шевеление на эту тему, но у них там какой-то свой особенный хипстерский мирок, в который я пока не вник.

Так это, я нахожу несколько странным вывод следующей программы:

(defclass extended-class (standard-class)
  (additional-slot) )
 
(defclass extended-object ()
  ()
  (:metaclass extended-class) )

(defun print-metaclass-slot-names (class-name)
  (let* ((metaclass (class-of (find-class class-name)))
         (metaclass-slots (class-slots metaclass))
         (slot-names (mapcar #'slot-definition-name metaclass-slots)) )
    (format t "~a: ~a~%" class-name slot-names) ) )
 
(print-metaclass-slot-names 'standard-class)
(print-metaclass-slot-names 'standard-object)
(print-metaclass-slot-names 'extended-class)
(print-metaclass-slot-names 'extended-object)
В CLOS отношение class-of по сути определяет набор слотов объектов. Почему стандартный класс метаобъектов сам определяет свой набор слотов, а пользовательские классы метаобъектов так делать не могут?

Например, я хочу создать иерархию наследования, независимую от существующей. Пусть в ней все классы будут обладать дополнительным слотом abstract, который говорит, применима ли к ним make-instance. То есть я такой создаю свой abstractable-class с этим слотом, его экземпляр называю abstractable-object — это альтернативный корень иерархии наследования, у которого abstract = nil. Но сам метаобъект класса abstractable-class не имеет этого слота, чем нарушает мою хотелку «все классы (новой иерархии) имеют слот abstract».

 , ,

ilammy
()

Рекурсивные вычисления на шаблонах C++

Я написал (для прикола) интерпретатор лямбда-исчисления на шаблонах. Вроде всё окей. Написал арифметики и функцию вычисления факториала. Написал Y-комбинатор и попробовал вызвать факториал... не компилируется (километр ошибок, так что я пока не особо понял, где прокол). Написал через Z-комбинатор — компилятор уходит в бесконечный цикл. Код здесь, компилить с -std=c++11.

Кажется, проблема в ненормальном (во всех смыслах) порядке раскрытия шаблонов и отсутствии их унификации. Пока я раскуриваю стандарт на эту тему, вот вам вопрос: можно ли написать на шаблонах C++ вычислитель лямбда-термов, выполняющий редукцию в нормальном порядке, дабы рекурсия нормально работала?

(В теории типов и прочем борще не шарю. Может, проблема как раз в попытке погрузить бестиповое лямбда-исчисление в систему типов C++.)

/cast anonymous

 , , ,

ilammy
()

Динамические возможности CLOS

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

Является ли эта динамичность намеренно реализованной киллер-фичей собственно CLOS или это просто побочный эффект образо-ориентированного подхода к разработке на Common Lisp?

 , ,

ilammy
()

Набор (не простой) математики в DocBook

Здравствуй Лор, есть одна книга, набрана в LaTeX. Но я осознал, что PDF не особо удобен для распространения в электронном виде. А конвертеры LaTeX → HTML (из которых у меня завелась только Hevea) — это тихий ужас. Решил всё перетащить на DocBook, чтобы потом наваять пачку XSLTшек и быстро клёво конвертировать текст в различные форматы.

Но есть проблема: LaTeX это язык программирования для людей, а XML — язык разметки для машин. Первое удобно читать, но невозможно парсить. Второе — наборот. Поэтому там, где в изначальном тексте определена пара удобных ad hoc макросов, в XML приходится или писать абсолютно несемантические простыни, или в очередной раз расширять схему докбука специальным тегом.

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

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

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

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

Есть кто-то, кто набирал математику сложнее «а³ + b³ ≠ c³» (с хитрым выравниваем по горизонтали/вертикали, пачкой символов, собранных на коленке, и прочим) в XML-форматах? Ну, или кто-то, у кого есть позитивный опыт использования LaTeX → HTML конвертеров в том же случае?

А может, стоит просто забить <фраза><слово>на</слово><словосочетание><слово>весь</слово><слово>этот</слово></словосочетание><словосочетание><слово>тихий</слово><слово>ужас</слово></словосочетание></фраза>, простые макросы перегнать регэкспами, а формулы — в PNG, потому что потом те же проблемы возникнут с MathJax?

Или вообще забить на этот HTML, опубликовать PDF, к которому страничная разбивка прибита гвоздями (ну, и сверстать там варианты под три с половиной популярных читалки + по вкусу для мониторов), а кому так будет надо, то пусть сам <эвфемизм>занимается утехами</эвфемизм> со своим хатээмелем? Всё равно книга переводная под CC-BY-ND.

Энивей, мне действительно интересно, как эту проблему можно удобно решить именно для XML-based вёрстки. В данный момент я вижу только написание очередного специфичного софта.

 , , ,

ilammy
()

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