LINUX.ORG.RU

Лисп. Точечные пары.

 


2

3

С недавних пор взялся за изучение лиспа и никак не могу нигде найти инфу, зачем нужны точечные пары. Я знаю, что любой список является в Лиспе точечной парой, прошу не объяснять, об этом везде пишется. Но неясно, почему нельзя, как бы, выпилить вообще эти точки, на мой взгляд, нет такой ситуации, где нельзя было бы обойтись просто списками. Собственно, в Newlisp, ЕМНИП, так оно и сделано. Единственным мыслимым применением точечных пар, мне представляется ситуация, когда из точечной пары достается хвост, который не является списком, например, (cdr (1 . 2)), но очевидно, что здесь мы могли бы тоже обойтись списком и доставать 2 значение с помощью cadr. Создается такое ощущение, что эта структура имела какое то особенное значение в старых лиспах, а сейчас осталась как атавизм.

Какой же настоящий смысл данной структуры?


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

Вообще, про тебя говорили, что ты больше не нюхаешь спиды, а тупо бухаешь. Это тебя от бухла так прёт? Или за старое взялся?

anonymous
()
Ответ на: комментарий от x4DA

Спали плз где нормальная гигиеническая макросистема «сольет» этому уродцу.

Ну, попробуй вот такую игрушку:

at-list-two проверяет 2 совпадения из произвольного количества аргументов, и в случае, если любые 2 из них совпали, выскакивает, не вычисляя оставшиеся (лень) и возвращает true , в противном случае - nil.

(define-macro (at-least-two)
              (let (c)
                   (doargs (i (= c 2))
                           (if (eval i)
                               (inc c)))
                   (>= c 2)))

;проверяем
(println (at-least-two (= 1 1)
                            (= 3 2)
                            (= 2 5)
                            (= 2 20)))



(println (at-least-two (= 1 1)
                            (= 3 2)
                            (= 5 5)
                            (= 2 20)))

;nil
;true

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

если любые 2 из них совпали

В смысле, любые 2 выражения из ряда аргументов, возвратили true

//fixed

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

Вообще, про тебя говорили, что ты больше не нюхаешь спиды, а тупо бухаешь. Это тебя от бухла так прёт? Или за старое взялся?

Он же в Питер перебрался (работать сисярп-кодером, лол). А в Питере, я слышал, особенно популярны псилоцибы. Так что они, скорее всего.

anonymous
()
Ответ на: комментарий от phill

попробуй «конкурентно» с сикпом полистать Хювененов 2ух томник мир лиспа листа для «банальной эрудиции»

«и ты поймёш , что значение 2 это платонова идея, если ты измениш у символа 2 значение на значение 4 то ты ещё более качественно выстрелиш себе в ногу , чем предложенные тобой варианты выше по треду»

в сикпе схема вообще говорят не важна ибо на неё авторы обещают потратить только 2 часа в начале курса , важно , что в сикпе есть всё необходимое(чесно говоря куча лишнего ) для курса «вхождение в программирование»

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

тонко

зы. с конкурентами нужно нежно , как с детьми, да.

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

ага, знание , что слово провокация дословно «возглас» и идёт с митинга требований (во времена гуситов) к имперской власти кое-кого , завершившиеся «аналогом бостонского чаепития» тока не спричала , а с балкона , и не чая , а ....

ну ты понял.

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

серьёзно?

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

qulinxao ★★☆
()
Ответ на: комментарий от anonymous
#lang racket

(define-syntax (at-least-two stx)
  (syntax-case stx ()
    [(_ args ...) 
     #'(eq? 2 (for/fold ([c 0]) ([x (syntax->list #'(args ...))] 
                   #:break (eq? c 2))
              (if (eval (syntax->datum x))
                  (+ c 1) c)))]))

(printf "first: ~a\n"  (at-least-two 
                      (eq?  1 1) 
                      (eq?  3 2) 
                      (eq?  2 5)
                      (eq?  2 20)))

(printf "second: ~a\n" (at-least-two 
                            (eq? 1 1)
                            (eq? 3 2)
                            (eq? 5 5)
                            (eq? 2 20)))

x4DA ★★★★★
()
Последнее исправление: x4DA (всего исправлений: 2)

Вижу, что западники и тут успели насрать.

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

Во-первых,

(define-syntax (at-least-two stx)
  (syntax-case stx ()
    [(_ args ...) 
     (datum->syntax stx
      (eq? 2 (for/fold ([c 0])
                       ([x (syntax->list #'(args ...))] 
                        #:break (eq? c 2))
              (if (eval (syntax->datum x))
                  (+ c 1) c))))]))

Во-вторых, не совсем верно, так как не будет работать

(let ([a 1])
  (at-least-two 
   (eq?  a a) 
   (eq?  2 2) 
   (eq?  2 5)
   (eq?  2 20)))

Кстати, а в newlisp будет?

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

А вот так работает в любом контексте:

(define-syntax-rule (at-least-two a ...)
  (let ([c 0])
    (let/ec return 
      (when a (set! c (add1 c)) 
        (when (= c 2) (return #t))) ... 
      #f)))

monk ★★★★★
()
Ответ на: комментарий от anonymous
#lang racket/base

(require (for-syntax racket/base))

(define-syntax-rule (at-least-two1 e ...)
  (let/ec exit
    (let ([s 0])
      (when e
        (when (s . = . 1)
          (exit #t))
        (set! s (add1 s)))
      ...
      #f)))

(define-syntax (at-least-two2 stx)
  (define (helper es sum)
    (if (null? es)
        (syntax #f)
        (let ([new-sum (car (generate-temporaries '(new-sum)))])
          #`(let ([#,new-sum (if #,(car es) (add1 #,sum) #,sum)])
              (if (#,new-sum . = . 2)
                  #t
                  #,(helper (cdr es) new-sum))))))
  (syntax-case stx ()
    [(_ e ...)
     (helper (syntax->list #'(e ...)) #'0)]))

Довольно тривиальная задача, и eval тут не нужен.

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

Кстати, а в newlisp будет?

Проверил щас, работает этот код в Newlispe, там ЕМНИП, оператор сравнения вообще универсален, почему бы ему не работать, собственно, если выражение (= a a), возвращает true.

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

почему бы ему не работать, собственно, если выражение (= a a), возвращает true

eval в лексической области видимости a. Почти для всех лиспов (let ((a 1)) (eval 'a)) работать не будет.

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от dave

man alist

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

(w (cadr (assq 'a '((b 1) (a 2) (c 3))))); -->2
(w (cdr (assq 'a '((b . 1) (a . 2) (c . 3))))); -->2
Так что это не ответ на вопрос.

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

А где там миллион букв? Там два варианта, делающих одно и тоже. Оба без eval. По кол-ву букв не намного длиннее.

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

Точнее, не делающих одно и тоже, а дающих одинаковый результат.

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

В Newlisp динамический биндинг по дефолту.

охлол, это вообще пушка.

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

Чот не догоняю почему первый вариант не работает. Потому что у x синтаксический контекст макра, а не места где макра раскрылась?

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

Потому что у x синтаксический контекст макра, а не места где макра раскрылась

eval вообще не умеет лексический контекст:

(let ([a 1])
  (eval '(eq? a a)))

a: undefined;
 cannot reference an identifier before its definition

Если очень хочется, приходится делать что-то вроде

(define-syntax (lexical-eval stx)
  (syntax-case stx ()
    [(_ cmd) #'(eval cmd)]
    [(lexical-eval cmd var ...)
     #'((eval `(lambda (var ...) ,cmd)) var ...)]))

(let ([a 1]) (lexical-eval '(+ a 1) a)) ; => 2

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

Какой гребаный ад, и эти люди еще пытаются нас убидить, что лиспы — выразительные языки, lol.

anonymous
()
Ответ на: комментарий от x4DA

eval же запускает все с чистым контекстом.

А разве не с глобальным? Или это зависит от второго параметра eval: interactive-environment (и еще какие то 2 там есть, ЕМНИП)?

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

А разве не с глобальным?

да, сорь, подефолту так и есть:

Вторым параметром указывается неймспейс, подефолту он = (current-namespace), то есть все top-level definitions будут там доступны.

http://docs.racket-lang.org/reference/eval.html?q=eval#(def._((quote._~23~25k...

x4DA ★★★★★
()

не троллинга ради. А зачем нужны массивы? Классические(не extended)? Их тоже можно заменить списками. А насчёт пар, лично я пользуюсь когда нужно «склеить» два промежуточных результата где-нибудь не в топлевеле, в остальных случаях я пользуюсь списками, множественными значениями и структурами.

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

А зачем нужны массивы? Классические(не extended)? Их тоже можно заменить списками

У массива время доступа к элементу O(1), у списка - O(n)

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

Насколько я себе это представляю (а представляю я это себе очень плохо), на низком уровне индексированный элемент все равно достается перебором. Это просто сахар для языка, невозможно волшебным образом получить элемент по индексу, если низкоуровневая реализация не переберет таблицу ключ-значение. И мы приходим к выводу, что высокоуровневые конструкции засирают нам мозг, и скрывают то, что происходит на самом деле:)

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

Зачем перебирать? Реализации ЯП известен размер элемента, стартовый адрес и индекс.

Путем нехитрый преобразований за константное время можно обратиться к элементу по индексу.

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

Я тоже не понимаю, зачем идиотов с лора в чём-то убеждать

vonenij
()
Ответ на: комментарий от lovesan

Да, я тоже не понимаю, зачем это говно типа Pico/NewLisp надо. Раньше я думал это из-за того, что они легковесные. А потом я узнал, что есть ISLisp (ну и реализации типа tisl)

vonenij
()
Ответ на: комментарий от anonymous
(define-simple-macro (at-least-two e:expr ...)
  (let ([c 0])
    (for ([l (list (λ () e) ...)]
          #:when (l)
          #:break (= c 2))
      (set! c (add1 c)))
    (>= c 2)))
anonymous
()
Ответ на: комментарий от x4DA

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

pseudo-cat ★★★
()
Ответ на: комментарий от x4DA

Это только если все преобразователи верят, что сложение - константная операция для любых чисел

anonymous
()
Ответ на: комментарий от pseudo-cat

Ход рассуждения - ты (не тролинга ради, как сам написал) спросил зачем нужны массивы. Полезность точечных пар, думаю, всем понятна (кроме автора newlisp)

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

ты не распознал мой еврейский ход, это был вопрос на вопрос)

pseudo-cat ★★★
()
Ответ на: комментарий от vonenij

Да, я тоже не понимаю, зачем это ... типа Pico/NewLisp надо.

Надобность определяется наличием вождя вроде Гвидо для питона.

Не надо думать. С нами тот кто все за нас решит

antares0 ★★★★
()
Последнее исправление: antares0 (всего исправлений: 1)

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

unlog1c ★★★
()

вот тебе немодный(45 лет) буклет (70страничек)

Дж.Фостер Обработка списков. Математическое обеспечение ЭВМ. М:МИР,1974

J.M. FOSTER List Processing . MACDONALD:LONDON 1968

Я знаю, что любой список является в Лиспе точечной парой

«что для одного человека константа то для другого переменная»

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

однако загляни на стр 32 вышеуказаного буклета - как раз пример точечной тройки.

Программирование - это способность думать на нескольких уровнях абстракции одновременно.

Мышление - есть способность думать о чём либо на нескольких уровнях абстрации .

к слову почему «простейшая» тема косвенности (то биш указателей) оказывается тем достаточно эффективным фильтром среди обучаемых.

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