LINUX.ORG.RU

Сообщения monk

 

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

Форум — Desktop

Стоит компьютер с KVM. При переключении Linux теряет монитор и выставляет разрешение 1024x768.

Переключаю обратно, разрешение включается не сразу, приходится запускать gnome-control-center display

Можно как-то отключить это автоопределение?

 ,

monk
()

Имена переменных и знание языка

Форум — Development

Вроде как надо называть переменные (а также программные файлы) на правильном английском языке даже если программу предполагается использовать только на территории РФ.

В связи с этим вопрос: как вы находите правильные термины?

Вот например, понадобилось сделать печатную форму оборотной ведомости. Иду в гугл и он мне предлагает negotiable bill, иду на yandex — там предлагается turnover sheet. Нутром чую что второй вариант правильней, но доказать не могу. И, самое главное, спросить-то некого. Заказчик отчёта — нормальный русский бухгалтер, знающий кроме русского только немецкий.

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

 ,

monk
()

Как жить без call/cc? Посоветуйте алгоритм решения

Форум — Development

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

Реализация на Scheme:

(define (walk-tree fn tree)
  (if (cons? tree)
      (begin
        (walk-tree fn (car tree))
        (walk-tree fn (cdr tree)))
      (fn tree)))

(define (compare-trees tree1 tree2)
  (call/cc 
   (lambda (return)
     (define caller #f)
     (define (yield-cont)
       (walk-tree proc1 tree1)
       (caller #f))     
     (define (yield)
       (call/cc
        (lambda (k)
          (set! caller k)
          (yield-cont))))
     (define (proc1 x)
       (call/cc
        (lambda (continue)
          (set! yield-cont (lambda () (continue #f)))
          (caller x))))
     (define (proc2 x)
       (unless (eqv? x (yield))
          (return #f)))
      (walk-tree proc2 tree2)
     (return (eq? (yield) #f)))))

Как написать такое без продолжений? Можно на Scheme/Java/C++/чём угодно.

 ,

monk
()

Анализ пользователей Common Lisp и Racket

Форум — Development

Common Lisp разрабатывался и используется в предположении, что пользователь программы — программист. Поэтому из языка намеренно исключены сложные для понимания конструкции (пользователь не обязательно квалифицированный программист), поэтому в языке мощнейший отладчик, позволяющий без остановки программы переопределять функции и вообще делать что угодно. Но из-за этого документация по большей части библиотек Common Lisp существует только в виде docstring и комментариев в коде (некоторые вообще считают, что код сам себе документация). Из-за этого обработка ошибок почти всегда оставляется на отладчик (главное сделать рестарт «перезапустить с последней итерации», а там пользователь сам разберётся). Из-за этого в программе проверяется только happy path (пользователь ведь «тоже программист»).

Racket разрабатывался и используется в предположении, что пользователь программы не программист, а задача разработчика написать программу так, чтобы она корректно работала при любых входных данных (если данные некорректны, то сообщала об этом в том месте, где данные были введены). Поэтому в языке эффективная библиотека для написания тестов, система контрактов на уровне модулей, макимально широкий спектр инструментов программирования (разработчик должен быть профессионалом!). Также реализована идея инкапсуляции: считается, что пользователь модуля не должен знать особенности реализации и, более того, не может в своём коде изменить функцию чужого модуля если это явно не разрешено разработчиком того модуля. Исходный код разумеется доступен, но его не требуется смотреть, чтобы использовать модуль. Достаточно документации. Поэтому реализована мощнейшая система документировния Scribble, а при реализации макроса есть возможность обеспечить указание на ошибки в коде, предоставленном макросу пользователем, не показывая потроха макроса.

И поэтому в Racket нет CLOS (есть как минимум две реализации, но не используются) - провоцирует заплаточное программирование (monkey patching), поэтому отладчик намеренно ограничен (если ты отлаживаешь программу, значит ты не знаешь как она должна работать!), поэтому нет разработки в образе (image based) - она провоцирует разработку через отладку (а значит непонимание программы и проверку только happy path).

Таким образом, Racket и Common Lisp несмотря на внешнее сходство являются очень разными языками. И я рекомендую писать на Racket, если только конечными пользователями программы не являются исключительно программисты на Common Lisp.

Взято с http://racket-lang.blog.ru/#post214726099

Хотелось бы знать, что по этому поводу думают пользователи ЛОРа. А также, мне кажется, что для Java и C++ будет где-то такая же разница.

 , ,

monk
()

Как заставить нормально работать stacktrace в Racket?

Форум — Development
#lang racket
(define (foo x) (/ 1 x))
(define (bar x) 
  (define res (foo (- x 1))) res)
(bar 1)

В stacktrace попадает вызов bar, определение bar целиком и вызов (/ 1 x).

Как сделать, чтобы попал вызов (foo (- x 1)) ?

 

monk
()

Структура БД, union type

Форум — Development

Задача:

есть таблица событий, в ней есть поле source.

В этом поле должна быть ссылка на объект, который зарегистрировал событие (далее. источник).

Источник может относится к одному из около 500 типов. Каждый тип — отдельная таблица.

Насколько я понимаю, в SQL нельзя сделать ссылку, которая содержала бы имя таблицы. Или можно?

Придумывается что-то вроде source_type int, source_id int, где source_type — номер таблицы и source_id — id в той таблице. Но 1) что делать с ссылочной целостностью (забить?) 2) как джойнить, если надо отфильтровать по полю регистратора?

У меня фильтрация получается что-то вроде

select e.* from events e
where (e.source_id, e.source_type) in
(select id, 1 from source1 where key_field = $1
union all
select id, 2 from source2 where key_field = $1
union all
....
union all
select id, 500 from source500 where key_field = $1)

Есть что-то проще? Или лучше для таких задач брать nosql?

 ,

monk
()

Кто хотел лисп, компилирующийся в C++?

Форум — Development

Нашёл на просторах Интернета: https://bitbucket.org/ktg/l/src/337c13802c5e?at=master

Умеет макросы

(define-syntax sum
  (syntax-rules ()
    [(sum) 0]
    [(sum a) a]
    [(sum a b) (+ a b)]
    [(sum a b ...) (+ a (sum b ...))]))

(define-syntax-rule (infix a op b) (op a b))

(define-syntax-rule (ret a) (return a))

(defmacro unless (pred a b)
  `(if (not ,pred) ,a ,b))

(main
  (prn (sum 1 2 3 4))
  (prn (infix 1 + 2))
  (unless false (prn "Will print") (prn "Will not print"))
  (ret 1))

Примеры смотреть в https://bitbucket.org/ktg/l/src/337c13802c5e/ex/?at=master

Хвалите и критикуйте!

 , ,

monk
()

Как читать документацию по OpenOffice?

Форум — Development

Помогите, может я не туда смотрю?

http://www.openoffice.org/api/docs/common/ref/com/sun/star/sheet/Spreadsheets...

Написано — реализует XIndexAccess, в котором на getByIndex написано «Return type = any, the element at the specified index».

Где найти, какой тип на самом деле возвращается интерфейсом?

 , ,

monk
()

существует ли стабильный ABI для Qt?

Форум — Development

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

Когда-то был qt-c. Потом был cpp-кусок от qtjambi. Вроде тоже помер. Сейчас смотрю, что в PyQt свой мегавелосипед (SIP — интерфейс из питона к C++), PerlQt — закончился в 2003 году, RubyQt — требует развернуть mingw.

Qt теперь снова только для С++ (и Python)?

 ,

monk
()

В чём делать шаблоны документов?

Форум — Development

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

По ним есть утверждённые формы (шрифты, отступы, изображения...).

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

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

Пытаюсь выбрать между html и latex. Вроде latex лучше: результат всё равно ожидается только на печати, но в html проще с шрифтами, да и wysiwyg есть...

Ваши мнения?

 , ,

monk
()

Почему в scheme не любят set! ?

Форум — Development

Может, кто-нибудь знает, почему в Scheme (и в Racket) не приянто использовать set!, особенно в списках

Например, если мне надо список разделить на два по «выполняется/не выполняется условие», то в CL это будет выглядеть как

(defun split (list pred)
  (let ((res1 nil) (res2 nil))
     (dolist (l list)
        (if (pred l)
            (push l res1)
            (push l res2)))
     (values (nreverse res1) (nreverse res2))))

На Scheme полный аналог

(define (split list pred)
  (let ([res1 null] [res2 null])
     (for-each (lambda (l)
                 (if (pred l)
                    (set! res1 (cons l res1))
                    (set! res2 (cons l res2))))
          list)
     (values (reverse res1) (reverse res2))))

Но в учебниках по Scheme пишут, что так писать очень плохо, а надо так:

(define (split list pred)
   (define (loop list res1 res2)
     (cond
       [(null? list) (values (reverse res1) (reverse res2))]
       [else
         (if (pred (car list))
             (loop (cdr list) (cons (car list) res1) res2)
             (loop (cdr list) res1 (cons (car list) res1)))]))
   (loop list null null))
,мол, это понятнее.

Помогите понять, в чём смысл?

 , ,

monk
()

Помогите сделать макрос красивым

Форум — Development

Сделал, чтобы Racket мог создавать функции на основании их описания из GObjectIntrospection. Сейчас смотрю на то, что получилсоь и понимаю, что «настоящий программист может написать программу на ФортранеКоммон Лиспе на любом языке».

Задача стоит так: есть описание функции в виде описаний входящих и исходящих параметров (исходящие — значит по ссылке). _fun использовать нельзя, так как массив передаётся в FFI (и если исходящий, то собирается из) двух параметров: указатель + длина.

Прошу совета как сделать правильно. Сейчас build-function строит исходный текст подстановки макроса (в стиле defmacro), а затем build-ffi подтсавляет его в datum->syntax.

Если пытаться делать без datum->syntax, то вылазят две проблемы: что делать с локальными define'ами и как генерировать имена переменных. С другой стороны, надеюсь решить проблему с именаим параметров: у меня сейчас !arg — входящий параметр, %arg — он же, преобразованный в Си, &arg — указатель на него.

(define-syntax (define-gi-definer stx)
  (syntax-case stx ()
    [(_ id) #'(define-gi-definer id id)]
    [(_ id repository)
     (with-syntax ([string-rep (->string (syntax-e #'repository))])
       (repository-require (syntax-e #'string-rep))
       #'(define-syntax (id stx)
           (syntax-case stx ()
             [(_ object) 
              (with-syntax ([string-obj (->string (syntax-e #'object))])
                (hash-ref! instance-hash (cons string-rep (syntax-e #'string-obj)) 
                           (λ () (syntax-local-lift-expression 
                                  (build-ffi stx (syntax-e #'string-rep) (syntax-e #'string-obj))))))])))]))

(define-for-syntax (build-ffi stx rep obj)
  (define res (find-gi rep obj))
  (datum->syntax stx res))

(define (find-gi repository name)
  (define info (rep:find repository name))
  (unless info
    (raise-argument-error 'find-gi "name of object in repository" name))
  (define type (g-base-info-get-type info))
  (case type
    [(constant) (const-value info)]
    [(function) (build-function info)]))

(define (build-function info)
  (define %args (args info))
  (define (in-arg? arg) (memq (g-arg-info-get-direction arg) '(in inout)))
  (define (out-arg? arg) (memq (g-arg-info-get-direction arg) '(out inout)))
  (define (array-pos arg)
    (define type (g-arg-info-get-type arg))
    (if (eq? (g-type-info-get-tag type) 'array)
        (g-type-info-get-array-length type)
        -1))
  (define res-type-symbol (tag->symbol_type
                           (g-type-info-get-tag (g-callable-info-get-return-type info))))
  (define fun-type (append (list '_fun)
                           (for/list ([arg (in-list %args)])
                             (if (out-arg? arg) '_pointer ((tag->symbol_type
                                                            (g-type-info-get-tag (g-arg-info-get-type arg))))))
                           (list '-> res-type-symbol)))
  
  (define vector-lengths (for/list ([arg (in-list %args)] 
                                    #:when (> (array-pos arg) -1))
                           (list-ref %args (array-pos arg))))
  (define in-args (filter (λ (arg) (and (not (memq arg vector-lengths)) (in-arg? arg))) %args))
  (define out-args (filter out-arg? %args))
  (define ((prefix-name prefix) arg) (string->symbol (string-append prefix (g-base-info-get-name arg))))
  (define ref-name (prefix-name "&"))
  (define init-name (prefix-name "!"))
  (define parsed-name (prefix-name "%"))
  (define fun-args (for/list ([arg (in-list %args)]) 
                     (if (out-arg? arg)
                         (ref-name arg)
                         (parsed-name arg))))
  (define (array-of type-info) (g-type-info-get-tag (g-type-info-get-param-type type-info 0)))
  (define parse-exprs
    (for/fold ([define-parsed null])
      ([in-arg (in-list in-args)])
      (define type-info (g-arg-info-get-type in-arg))
      (define tag (g-type-info-get-tag type-info))
      (if (eq? (g-type-info-get-tag type-info) 'array)
          (cons `(define ,(parsed-name in-arg) (pvector-ptr ,(init-name in-arg) ,(tag->symbol_type (array-of type-info))))
                (if (> (array-pos in-arg) -1)
                    (cons `(define ,(parsed-name (list-ref %args (array-pos in-arg))) (pvector-length ,(init-name in-arg))) define-parsed)
                    define-parsed))
          (cons `(define ,(parsed-name in-arg) ,(init-name in-arg))))))
  (define-values (total define-outs set-outs out-refs)
    (call-with-values 
     (λ ()
      (for/fold ([sum 0] [define-outs null] [set-outs null] [out-refs null]) 
        ([out-arg (in-list %args)] #:when (out-arg? out-arg))
        (define type-info (g-arg-info-get-type out-arg))
        (define tag (g-type-info-get-tag type-info))
        (values (+ sum (ctype-sizeof (tag->_type tag)))
                (cons `(define ,(ref-name out-arg) ,(if (= sum 0) 'ptr `(ptr-add ptr ,sum))) define-outs)
                (if (in-arg? out-arg) 
                    (cons `(ptr-set! ,(ref-name out-arg) ,(tag->symbol_type tag) ,(parsed-name out-arg)) set-outs)
                    set-outs)
                (cond 
                  [(eq? tag 'array) 
                   (cons `(pvector ,(tag->symbol_type (array-of type-info)) 
                                   (ptr-ref ,(ref-name out-arg))
                                   ,@(if (> (array-pos out-arg) -1)
                                         (list `(ptr-ref ,(ref-name (list-ref %args (array-pos out-arg)))))
                                         null)) out-refs)]
                  [(not (memq out-arg vector-lengths)) 
                   (cons `(ptr-ref ,(ref-name out-arg) ,(tag->symbol_type tag)) out-refs)]
                  [else out-refs]))))
     (λ (sum l1 l2 l3) (values sum (reverse l1) (reverse l2) (reverse l3)))))
  `(let ([fun (get-ffi-obj ,(g-function-info-get-symbol info) #f ,fun-type)]) 
     (lambda ,(map init-name in-args)
       ,@parse-exprs
       ,@(if (> total 0)
             (append (list `(define ptr (malloc ,total)))
                     define-outs)
             null)
       ,(if (eq? res-type-symbol '_void)
            `(fun ,@fun-args)
            `(define res (fun ,@fun-args)))
       ,(if (eq? res-type-symbol '_void)
            `(values ,@out-refs)
            `(values res ,@out-refs)))))

Пример раскрытого макроса:
(let ((fun (get-ffi-obj "gtk_init" #f (_fun _pointer _pointer -> _void))))
   (lambda (!argv)
     (define %argv (pvector-ptr !argv _string))
     (define %argc (pvector-length !argv))
     (define ptr (malloc 8))
     (define &argc ptr)
     (define &argv (ptr-add ptr 4))
     (fun &argc &argv)
     (values (pvector _string (ptr-ref &argv) (ptr-ref &argc)))))

 , ,

monk
()

Интерпретация, компиляция, а это что?

Форум — Development

Если транслятор преобразовывает программу:

input i
let j = i * 2;
print j

в

#include "set_val.h"
hash vars;
int main()
{
   input("i");
   set("j", mult(val("i"), 2);
   print(val("j"));
}

где set, mult и val определены как

void set(char *key, variant & val)
{
   set_hash(vars, key, val);
}

variant val(char *key)
{
   return get_hash(vars, key);
}

variant mult(variant a, variant b)
{
   variant c;
   assert(a.type == NUMBER && b.type == NUMBER);
   c.type = NUMBER;
   c.number = a.number * b.number;
}

а затем при помощи gcc получает бинарник, то этот весь процесс является компиляцией или интерпретацией?

 ,

monk
()

Помогите найти алгоритм построения поверхности из точек

Форум — Development

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

 ,

monk
()

FFI, сложные типы данных, как лучше?

Форум — Development

Думаю по поводу того, как должен выглядеть идеальный FFI (foreign function interface) между языком со сборщиком мусора (например, лиспом) и Си.

Для простых типов всё хорошо. А вот что делать со строками, массивами и структурами?

Фактически варианта всего два: транслировать или оставлять указателем.

Вариант с трансляцией мне не нравится тем, что функция «изменить значение головы списка» превратится в «преобразовать весь список, изменить значение головного эдемента, преобразовать список обратно». Хотя видел решения с идеологией «транслировать всё». Например, cl-virgil.

Вариант «всё хранить указателями с тэгами» приводит к наличию в языке двух наборов типов. Строки языка и строки FFI, структуры языка и структуры FFI, массивы языка и массивы FFI. С разными функциями для работы с ними. Получаем протекающую абстракцию... вроде опять плохо.

Если кто-нибудь сталкивался с подобной проблемой, то по какому пути шли и почему?

 ,

monk
()

Как на макросах изобразить инстанциирование

Форум — Development

Есть макрос, который должен создавать функцию.

(defmacro build (info) `(lambda ...))

Текст функции зависит от содержимого структуры info.

Где-то в коде он многократно вызывается с разными параметрами. Можно ли как-то сделать, чтобы он при первом запуске где-то создавал функцию, а при последующих только ссылался на неё? То есть нужен механизм, аналогичный инстанциированию шаблонов C++.

Есть какие-нибудь идеи, как сделать? Реализация лиспа (CL, Scheme, ...) не важна.

 , ,

monk
()

Вдруг кому надо. G-Object-Introspection для Common Lisp

Форум — Development

Собственно, сабж: https://github.com/andy128k/cl-gobject-introspection

Документация есть. На простых примерах протестировано (HelloWorld в каталоге test)

 , ,

monk
()

Вычисления при компиляции в Racket

Форум — Development

Есть ли простой путь замены CL-овского #. ?

Например, кусок кода

(case ftype
                   ((#.(keyword->g-type :enum)
                       #.(keyword->g-type :flags))
                    (convert-to-foreign value (g-type->lisp type)))
                   (#.(keyword->g-type :double)
                      (coerce value 'double-float))
                   (#.(keyword->g-type :float)
                      (coerce value 'single-float))
                   ((#.(keyword->g-type :int)
                       #.(keyword->g-type :uint)
                       #.(keyword->g-type :long)
                       #.(keyword->g-type :ulong)
                       #.(keyword->g-type :int64)
                       #.(keyword->g-type :uint64)) (round value))
                   (t value))

Я, конечно, могу переписать через cond, но тогда при каждом вызове (внутри цикла) будет много-много поисков в словаре числа для ключевого слова.

Могу вручную выполнить (keyword->g-type :uint), (keyword->g-type :long) и подставить в код результаты. Но будет пачка «магических чисел» в коде. Причём, если в следующей версии будут другие числа у ключевых слов, придётся как-то искать все места использования.

Что посоветуете?

 ,

monk
()

XPath: помогите описать путь

Форум — Development

Хочу находить список объектов вида

<td>Сообщение:</td><td>(.*?)</td>

В смысле, нужно то, что в скобках.

Помогите написать правило XPath. Или хоть намекните, куда смотреть, чтобы на соседние ветки условие накладывать.

 ,

monk
()

Проверки во время компиляции.

Форум — Development

Предположим, что программа — интерфейс к БД. Насколько адекватно будет во время компиляции анализировать схему и на её основании генерировать классы, поля, контракты? Или хотя бы также (во время компиляции) проверять корректность написанных запросов.

Если неадекватно, то как правильно?

 , , ,

monk
()

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