Форум программистов, компьютерный форум, киберфорум
Языки JVM
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.88/26: Рейтинг темы: голосов - 26, средняя оценка - 4.88
28 / 13 / 1
Регистрация: 20.01.2013
Сообщений: 145
Записей в блоге: 8
1

Clojure Реализация ф-ций CONS, CAR, CDR (Sheme,CLisp)

05.11.2016, 12:16. Показов 5343. Ответов 47
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В книге SICP описан алгоритм реализации функций CONS,CAR,CDR на языке Sheme
Lisp
1
2
3
4
5
6
7
8
define (cons x y)
(define (dispatch m)
(cond ((= m 0) x)
((= m 1) y)
(else (error "Аргумент не 0 или 1 -- CONS" m))))
dispatch)
(define (car z) (z 0))
(define (cdr z) (z 1))
Вот как я реализовал в CLisp
Lisp
1
2
3
4
5
6
7
8
9
10
(defun cons(x y) 
(defun dispatch (m)
(cond 
((eq m 0) x)
((eq m 1) y)
((and(not (eq m 1))(not(eq m 0))) "Аргумент не 0 или 1")
))
)
(defun car(z)(funcall z 0))
(defun cdr(z)(funcall z 1))
Но, наверное, этот же алгоритм можно реализовать с помощью глобальных переменных defvar
Что-то типа этого
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
(defvar m 0)
(defvar x 0)
(defvar y 0)
(defun dispatch (m)
(cond 
((= m 0) x)
((= m 1) y)
((> m 1) "Arg is not 0 or 1")
))
(defun cons(x y) (dispatch m))
(defun car(z)(funcall z  0))
(defun cdr(z)(funcall z  1))
Но тут что-то не то. Как вызвать dispatch из cons,вызвать cons из car или cdr
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.11.2016, 12:16
Ответы с готовыми решениями:

Композицией базовых функций CAR, CDR, CONS, LIST
Добрый день! прошу помочь в решении задачи: Композицией базовых функций CAR, CDR, CONS, LIST...

Lisp. По какому принципу работают функции CAR,CDR,CONS?
Здравствуйте! Помогите пожалуйста понять как работают функции CAR,CDR,CONS. Например, есть список:...

Работа со списками в LISP, используя базовые функции CAR, CDR, CONS
Дан список ( (A B ( C ) ) (D (E) (K L M))) получить: список (C) список (A B C D) ...

Заменить каждый второй элемент списка на 0,используя только рекурсию, CAR, CDR, CONS,COND
Заменить каждый второй элемент списка на 0,используя только рекурсию, CAR, CDR, CONS,COND

47
Модератор
Эксперт функциональных языков программированияЭксперт Python
36601 / 20330 / 4220
Регистрация: 12.02.2012
Сообщений: 33,643
Записей в блоге: 13
05.11.2016, 17:04 2
Все это вызывает беспокойство... Cons - первичная (ядерная) функция. Вряд ли имеет смысл ее реализовывать. Да и код странный. Смысл cons в том, чтобы создать новую ячейку. Из приведенного кода этого не видно.
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
05.11.2016, 18:32 3
Спокойствие, только спокойствие! (С)
Эта реализация абстракции списка через замыкания меня в свое время тоже весьма впечатлила и вдохновила. И я долго и безуспешно пытался повторить ее на haskell - боролся с системой типов, никак не получалось реализовать как в оригинале, где динамическая типизация позволяет такое проделывать. Но зато я реализовал эту концепцию в следующих языках:

1) Ela - http://elalang.net/ - типа динамический haskell, очень удобно тем, кому статическая типизация больше мешает чем помогает Пример кода не сохранился, но там нетрудно повторить реализацию.

2) С++ - https://github.com/Ivana-/C-lambda-over-lambda - мой пример кота на гитхабе, в котором я через плюсовые лямбды (хранящие на стеке в виде замыканий свое содержимое) реализую абстракцию подобных списков, функции их трансформации (map / filter / fold и т.п.) и с помощью этих абстракций накостылил несколько типичных примеров алгоритмов на списках - числа Хэмминга и т.п.

3) Haskell - в конечном итоге удалось продраться через прокрустово ложе жесткой системы типов, но не без потерь - реализация выглядела не элегантно.

ЗЫ в общем, рекомендую ТС продолжать свои опыты. Конечно реализация через глобальные переменные имхо обречена на провал - вам нужна возможность создавать сколько угодно списков любой длины. Но сама забава в высшей степени интересна, как концепция и разминка для мозгов
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
05.11.2016, 20:33 4
Я не очень понял, каким боком тут глобальные переменные. Только замечу по мелочи, что числа нельзя сравнивать с помощью eq (это оговорено в стандарте), нужно использовать или eql, или =, и что переопределять функцию cl:cons нельзя: стандарт запрещает переопределять функции из пакета "CL", и ваш компилятор/интерпретатор должен ругаться. Также, язык называется Common Lisp, сокращается CL, а clisp - название одного из интерпретаторов.

Добавлено через 1 минуту
Кстати, в данном случае можно было пользоваться case.
0
188 / 155 / 17
Регистрация: 18.12.2015
Сообщений: 179
05.11.2016, 20:35 5
dserp18, а Ваш код вот так может?

Lisp
1
2
? (car (cdr (cons 1 (cons 2 3))))
2
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
05.11.2016, 21:42 6
rdt, я конечно не ТС, но если дать немного ума его коту, и убрать лишние символы и скобки, то вполне все получается:
Lisp
1
2
3
4
5
6
7
8
9
10
(defn f-cons (x y) 
    (lambda (m)
        cond (= m 0) x
             (= m 1) y
             "Аргумент не 0 или 1"))
(defn f-car (z) z 0)
(defn f-cdr (z) z 1)
=> OK
(f-car (f-cdr (f-cons 1 (f-cons 2 3))))
=> 2
2
Эксперт функциональных языков программированияЭксперт Java
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
06.11.2016, 21:25 7
Цитата Сообщение от helter Посмотреть сообщение
Кстати, в данном случае можно было пользоваться case.
Или обойтись только лямбдами. =)

Кликните здесь для просмотра всего текста
Lisp
1
2
3
4
5
6
7
8
9
(define (f-cons x y)
  (lambda (selector)
    (selector x y)))
 
(define (f-car pair)
  (pair (lambda (x y) x)))
 
(define (f-cdr pair)
  (pair (lambda (x y) y)))
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
06.11.2016, 21:32 8
Да, в том же SICP далее по ходу повествования приведен и такой чисто лямбдовый вариант
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
36601 / 20330 / 4220
Регистрация: 12.02.2012
Сообщений: 33,643
Записей в блоге: 13
06.11.2016, 22:20 9
А, вот что имеется в виду... Не понял сразу.
0
28 / 13 / 1
Регистрация: 20.01.2013
Сообщений: 145
Записей в блоге: 8
07.11.2016, 22:28  [ТС] 10
подскажите,будьте любезны, а что это за код?
Lisp
1
2
3
4
5
6
7
(defn f-cons (x y) 
    (lambda (m)
        cond (= m 0) x
             (= m 1) y
             "Аргумент не 0 или 1"))
(defn f-car (z) z 0)
(defn f-cdr (z) z 1)
Похоже на Clojure, только в Clojure надо писать
Lisp
1
defn f-cons [x y]
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
07.11.2016, 23:09 11
Это кот на самодельном диалекте под названием Лискрипт. Если вас смущает головная форма defn, то ее можно хоть горшком назвать. У меня она определена в стандартной библиотеке определена так:
Lisp
1
2
(def defmacro (macro (name args body) (def name (macro args body))))
(defmacro defn (name args body) (def name (lambda args body)))
0
621 / 941 / 150
Регистрация: 10.08.2015
Сообщений: 5,018
10.11.2016, 01:26 12
Цитата Сообщение от _Ivana Посмотреть сообщение
Если вас смущает головная форма defn
меня например смущает отсутствие скобок... с точки зрения лиспа это такая функция, которая возвращает функцию, которая возвращает строку
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
10.11.2016, 01:40 13
Цитата Сообщение от vlisp Посмотреть сообщение
меня например смущает отсутствие скобок...
Как скажете, могу еще парочку убрать - тоже работает:
Lisp
1
2
3
4
5
(defn f-cons (x y) 
    lambda (m)
        cond (= m 0) x
             (= m 1) y
             "Аргумент не 0 или 1")
1
621 / 941 / 150
Регистрация: 10.08.2015
Сообщений: 5,018
10.11.2016, 02:27 14
Цитата Сообщение от _Ivana Посмотреть сообщение
могу еще парочку убрать - тоже работает:
да хоть все
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
10.11.2016, 02:35 15
Цитата Сообщение от vlisp Посмотреть сообщение
да хоть все
Тогда получится haskell, только с динамической типизацией и строгим порядком вычислений
0
621 / 941 / 150
Регистрация: 10.08.2015
Сообщений: 5,018
11.11.2016, 19:30 16
Цитата Сообщение от _Ivana Посмотреть сообщение
Тогда получится haskell
не выдумывайте, у вас белиберда получилась и вообще не понятно что... скобки, неважно какие, круглые ли, фигурные ли или вообще из ключевых слов - обязательный атрибут сложных выражений. в лиспе такой код неизменно завершится ошибкой, потому что функция m не определена
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
11.11.2016, 19:34 17
Цитата Сообщение от vlisp Посмотреть сообщение
у вас белиберда получилась и вообще не понятно что...
Однако, мой интерпретатор (да и внутренний парсер в голове тоже ) не согласны с такими вашими оценками и вполне однозначно выполняют написанный кот И никаких лишних скобок не требуется.

ЗЫ если кому из менее эмоциональных участников одновременно интересно и непонятно - могу пояснить подробно как это парсится и трактуется.
0
621 / 941 / 150
Регистрация: 10.08.2015
Сообщений: 5,018
11.11.2016, 20:14 18
Цитата Сообщение от _Ivana Посмотреть сообщение
Однако, мой интерпретатор (да и внутренний парсер в голове тоже ) не согласны с такими вашими оценками и вполне однозначно выполняют написанный кот
ваш код звучит как шариков в первые часы жизни и с точки лиспа выглядит вот так
Lisp
1
2
3
4
5
6
7
8
9
10
(defn f-cons (x y) 
    lambda
    (m)
    cond
    (= m 0)
    x
    (= m 1)
    y
    "Аргумент не 0 или 1"
)
абр абр... что-то не так в парсере, который такое прожевывает
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
11.11.2016, 20:18 19
Ну как же кот может звучать как Шариков? Он же кот, а Шариков - собака Да и вообще он у меня молчаливый.

ЗЫ просто у вас парсер другой, шариковский. А у меня котовый. Отсюда и непонимание.
0
28 / 13 / 1
Регистрация: 20.01.2013
Сообщений: 145
Записей в блоге: 8
11.11.2016, 20:25  [ТС] 20
Ну, наверное, можно сделать такую реализацию Лиспа с отступами как в Python. Это уже кому что больше нравится.
0
11.11.2016, 20:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.11.2016, 20:25
Помогаю со студенческими работами здесь

каждый нечетный элемент списка умножить на 2, каждый четный на 3. использовать только рекурсию CAR,CDR,COND,CONS
каждый нечетный элемент списка умножить на 2, каждый четный на 3. использовать только рекурсию ...

car и cdr
Выделите с помощью комбинации вызовов “car” и “cdr” элементы x, y, z из следующих списков, а также...

Car и Cdr
Выделите с помощью комбинации вызовов “car” и “cdr” элементы x, y, z из следующих списков, а...

Композиция CAR и CDR
Помогите составить композицию из функций CAR и CDR, для которой результатом применения этой...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru