LINUX.ORG.RU

KISS языки


1

1

Кроме ближайших родственников Оберона. С тривиальным синтаксисом, интуитивной и формально определенной семантикой. Есть такие?

PS Брейнфак не предлагать.

PPS Желающие предложить СИ отправляются учить стандарт в целом, и лютое количество таких выкрутасов в частности.

★★★★★
Ответ на: комментарий от www_linux_org_ru

> использование http://en.wikipedia.org/wiki/Church_encoding вместо целых чисел, предоставляемых железом тоже «ничем не противоречит определению»; вот только я посмотрю, на сколько десятичных порядков программа начнет после этого тормозить (не меньше чем на 3, думаю)

но при чём тут «сложные» объекты

«сложный» должен тут означать не «много полей и методов», а что-то другое — например, немутабельные объекты проще мутабельных, строки проще объектов, держащих внутря себя ссылки с подсчетом; но и это не вся история

это я понял, но почему их нельзя (по-твоему) использовать в замыканиях?

я, например, люблю использовать хеш-таблицы в замыканиях. хеш-таблица — «сложный» объект?

korvin_ ★★★★★
()
Ответ на: комментарий от quasimoto

> Конечно это вид примитивного GC

посчет ссылок *можно* использвать как вид примитивного и неполноценного GC, но это не означает, что они *есть* вид примитивного GC

д-во:

1. GC заставляет периодически выгонять из из свопа в оперативку неиспользуемые страницы памяти, подсчет ссылок — нет

2. подсчет ссылок на строках обеспечивает гарантированное время удаления строки, GC на строках — скорее всего нет (хотя может и можно сделать)

в результате имеем GC — это такой вид примитивного посчета ссылок

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от korvin_

> я, например, люблю использовать хеш-таблицы в замыканиях. хеш-таблица — «сложный» объект?

ты чуть подробней расскажи что там, для чего, и что мутабельно

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Ну хотя бы обычный RC не работает с циклическими структурами (circular data structures), во-вторых смешивание инструкций gc с реальными инструкциями кода (инкрементальный/конкурентный сборщик, работающий в отдельном потоке даёт большой выигрыш при параллелизации).

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Естественно речь о использовании счётчиков в алгоритмах автоматического освобождения а не о самих счётчиках (сами счётчики как они есть вообще не нужны, разве что сказать «вот тут у нас выделилось уже 1 MB данных и 1000 объектов, ну и ладно пусть весят» ;))

quasimoto ★★★★
()
Ответ на: комментарий от www_linux_org_ru

гм хеш-таблица, допустим объектов некоего класса (или разных классов), доступ к которым осуществляется по символу-идентификатору, типа так:

(let ((instances (make-hash-table :test #'eq)))
  (defmethod make ((id symbol) (class-name symbol) &rest initargs)
    (make id (apply #'make-instance class-name initargs)))
  (defmethod make ((id symbol) instance &rest initargs)
    (setf (gethash id instances) instance))
  (defun find-instance (id)
    (gethash id instances)))
korvin_ ★★★★★
()
Ответ на: комментарий от quasimoto

> Этот пост я уже совсем не понял ;) RC это один из вариантов GC - к чему умствования?

RC это НЕ один из вариантов GC, так же как мотоцикл это не один из вариантов автомобиля

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

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от quasimoto

не, ну это понятно, я думал ему более конкретный пример нужен =)

korvin_ ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Я чуть ниже написал - тут мы рассматриваем RC в применении к автоматическому освобжению памяти, собственно GC, - это чтобы чистить окружения после создания замыканий.

quasimoto ★★★★
()
Ответ на: комментарий от Manhunt

>Семантика должна быть простой, чтобы хоть как-то облегчить ужасный пункт 3.

напиши все на XML, тогда валидация будет тривиальной

annulen ★★★★★
()
Ответ на: комментарий от korvin_

все равно не понял :-)

вообще с моей точки зрения замыкание — это облегченная синтаксическая форма для создания объекта;

думать решать «а надо ли собирать мусор для замыканий» надо так же, как и решать «а надо ли собирать мусор для объектов»

*отдельно* рассматривать замыкания надо (вроде) только в том аспекте, что было бы полезно, если бы вместо любой функции можно было бы пихнуть замыкание

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

что именно ты не понял? функции make и find-instance замыкаются на символ instances, который связывается с хеш-таблицей. make заносит в неё объект, find-instance возвращает по идентификатору, при этом сама хеш-таблица видна только этим функциям. инкапсуляция.

без замыканий это аналогично такому псевдокоду с модулями:

(module foo
  (provide make find-instance)
  
  (define instances (make-hash))

  (define (make ...) ...)

  (define (find-instance ...) ...))

(require foo)

просто замыкание в таком ключе — вещь «низкоуровневая», «базовая» =)

korvin_ ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> вообще с моей точки зрения замыкание — это облегченная синтаксическая форма для создания объекта;

не совсем. строить объекты (в ООПшном смысле, например как в С++) с помощью замыканий немного некрасиво и громоздко, нужен синтаксический сахар (макры/шаблоны)

так же и замыкания строить с помощью ООПшных объектов некрасиво и громоздко, опять нужен сахар (опять макры/шаблоны)

«замыкания — объекты для бедных, объекты — замыкания для бедных» // не-помню-чья

korvin_ ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> *отдельно* рассматривать замыкания надо (вроде) только в том аспекте, что было бы полезно, если бы вместо любой функции можно было бы пихнуть замыкание

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

korvin_ ★★★★★
()
Ответ на: комментарий от annulen

> напиши все на XML, тогда валидация будет тривиальной

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

Это не та валидация, которая представляет интерес.

Manhunt ★★★★★
() автор топика
Ответ на: комментарий от korvin_

> «замыкания — объекты для бедных, объекты — замыкания для бедных» // не-помню-чья

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

пока что я только понял, что у тебя типичный объект

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

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от korvin_

> ну в «функционально-ориентированных» языках, любая функция фактически является замыканием, только у некоторых пустое окружение.

ну так и тема «нам нужны замыкания» там бессмысленна; здесь же речь идет о си-подобных языках

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от korvin_

> не совсем. строить объекты (в ООПшном смысле, например как в С++) с помощью замыканий немного некрасиво и громоздко, нужен синтаксический сахар (макры/шаблоны)

так же и замыкания строить с помощью ООПшных объектов некрасиво и громоздко, опять нужен сахар (опять макры/шаблоны)

в лиспе никогда не было проблем с дефицитом макр (и круглых скобок) — так что причины эти надуманны

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

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от korvin_

* как ты заставишь лисп, чтобы он использовал замыкания, сделанные на основе объектов CLOS, точно так же, как и родные функции?

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>> Конечно это вид примитивного GC

посчет ссылок *можно* использвать как вид примитивного и неполноценного GC, но это не означает, что они *есть* вид примитивного GC

д-во:

1. GC заставляет периодически выгонять из из свопа в оперативку неиспользуемые страницы памяти, подсчет ссылок — нет

2. подсчет ссылок на строках обеспечивает гарантированное время удаления строки, GC на строках — скорее всего нет (хотя может и можно сделать)

в результате имеем GC — это такой вид примитивного посчета ссылок

ыыыы... чуваку, отсыпь, а?

Waterlaz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>> ыыыы... чуваку, отсыпь, а?

в переводе на русский «по фактам и логике возразить не могу, но очень хочется», так?

По факту то, что ты написал там доказательство, выдает в тебе больного ФГМ.

Waterlaz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> * как ты заставишь лисп, чтобы он использовал замыкания, сделанные на основе объектов CLOS, точно так же, как и родные функции?

1) зачем мне делать замыкания на основе объектов CLOS, если в CL есть нормальные замыкания и так?

2) обобщённые методы (которые являются объектами CLOS) заставили же =)

ну и вообще проблемы не вижу: reader-макру для символа #\( можно и переопределить... =)

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

reader-макру для символа #\( можно и переопределить... =)

хотя даже этого не понадобится, примерно так:

(defclass closure ()
  ; slot definition
  )

(defmacro closure (context args &body body)
  (let ((clsr (gensym "CLOSURE-")))
    `(let ((,clsr (make-instance 'closure
                                 ,context
                                 #'(lambda ,args ,@body))))
       #'(lambda (&rest args)
           (apply (closure-func ,clsr) args)))))
korvin_ ★★★★★
()
Ответ на: комментарий от Manhunt

>Под словами «валидация XML» подразумевается формальная проверка, что конкретный XML-документ соответствует стандарту XML.

не стандарту, а конкретной схеме. напиши схему своего будущего мира, а потом последовательными XSLT преобразованиями продвигайся к цели :)

annulen ★★★★★
()
Ответ на: комментарий от annulen

> не стандарту, а конкретной схеме

Это несущественная деталь. Надеялся, что ты не будешь к ней цепляться.

Manhunt ★★★★★
() автор топика
Ответ на: комментарий от annulen

> с помощью таких штук как www.gccxml.org/HTML/Index.html тотальная валидация становится менее фантастичной

gccxml всего лишь дает тебе внутреннее представление GCC. Построить на этом валидатор Си++ - задача, мягко говоря, трудная (даже если считать gccxml безбажным).

tailgunner ★★★★★
()
Ответ на: комментарий от annulen

> По-моему существенная

Ок, если существенная, давай разберем конкретный пример. Пусть я набыдлокодил на xml тривиальную сортировку «пузырьком». Как средствами xml-валидаторов и xml-схем доказать, что некий написанный на xml код в самом деле сортирует входную последовательность, и делает это не больше, чем за O(n^2) операций? :D

Manhunt ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

> gccxml всего лишь дает тебе внутреннее представление GCC

и по тому, что я глядел, он не дает внутреннее представление шаблонов, пригодных для инстанциирования, но не инстанциированных

для рефлексии это самое то, для экспорта внутреннего представления GCC  — совершенно не подходит

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

ммм... и ты хочешь сказать, что (eval '(korvin_closure 3 2 1 17)) сработает так же, как и (eval '(some-lisp-function 3 2 1 17)) ?

да

(defpackage #:closure
  (:use #:cl)
  (:export
   #:closure
   #:defclosure))


(in-package #:closure)


(defclass closure ()
  ((closure-environment
    :initform (vector)
    :initarg  :env
    :accessor closure-env
    :type     vector)
   (closure-function
    :initform #'(lambda () nil)
    :initarg  :func
    :accessor closure-func
    :type     function)))

(defmacro closure (args &body body)
  (let* ((clsr (make-instance 'closure))
         (ctxt (make-ctxt clsr args)))
    `(progn
       (setf (closure-func ,clsr)
             #'(lambda ()
                 (symbol-macrolet ,ctxt
                   ,@body)))
       #'(lambda ,args
           ,(bind-env args clsr)
           (funcall (closure-func ,clsr))))))

(defun make-ctxt (clsr args)
  (loop :for x :in args
        :for i :upfrom 0
        :collect `(,x (elt (closure-env ,clsr) ,i))
        :into ctxt
        :finally (progn
                   (setf (closure-env clsr)
                         (make-array (list (1+ i))))
                   (return ctxt))))

(defun bind-env (args clsr)
  `(progn
     ,@(loop :for x :in args
             :for i :upfrom 0
             :collect `(setf (elt (closure-env ,clsr) ,i) ,x))))

(defmacro defclosure (name args &body body)
  (let* ((clsr (make-instance 'closure))
         (ctxt (make-ctxt clsr args)))
    `(progn
       (setf (slot-value ,clsr 'closure-function)
             #'(lambda ()
                 (symbol-macrolet ,ctxt
                   ,@body)))
       (defun ,name ,args
         ,(bind-env args clsr)
         (funcall (closure-func ,clsr))))))
CL-USER 31 > (defpackage #:closure-user
               (:use #:cl #:closure))
#<The CLOSURE-USER package, 0/16 internal, 0/16 external>

CL-USER 32 > (in-package #:closure-user)
#<The CLOSURE-USER package, 0/16 internal, 0/16 external>

CLOSURE-USER 33 > (defclosure foo (x)
                    (closure (y)
                      (closure (z)
                        (+ x y z))))
FOO

CLOSURE-USER 34 > (foo 1)
#<anonymous interpreted function 200F9A6A>

CLOSURE-USER 35 > (funcall (funcall (foo 1) 2) 3)
6

CLOSURE-USER 36 > (defclosure bar (x)
                    (closure (y)
                      (closure (x)
                        (+ x y))))
BAR

CLOSURE-USER 37 > (funcall (funcall (bar 1) 2) 3)
5

CLOSURE-USER 38 > 
CL-USER> (load "/home/korvin/p/cl/1/closure.lisp")
T

CL-USER> (use-package '#:closure)
T

CL-USER> (defclosure korvin-closure (a b c)
	   (+ a b c))
KORVIN-CLOSURE

CL-USER> (defun some-lisp-function (a b c)
	   (+ a b c))
SOME-LISP-FUNCTION

CL-USER> (eval '(korvin-closure 1 2 3))
6

CL-USER> (eval '(some-lisp-function 1 2 3))
6

CL-USER> 
korvin_ ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.