Запуск функций Python в CLISP

Доступны ли исходники CLISP? Я мог найти только ссылки на Stack.

Я пытаюсь запустить определение python в CLISP — какие-либо предложения о том, как мне это сделать? Я неплохо разбираюсь в написании определений в CLISP, но не в python... для начала я хочу переписать это из python:

def f(x):
if x <= 1/2:
    return 2 * x
if x > 1/2:
    return 2*x - 1

Просто чтобы посмотреть, как CLISP справляется с вычислением дробей в качестве сравнения, я собирался запустить это, которое я взял из онлайн-курса вычислительной алгебры:

x = 1/10
for i in range(80):
    print(x)
    x = f(x)

Благодарен за любые предложения...

Ваше здоровье.


person johnny_trfc    schedule 18.04.2020    source источник
comment
пожалуйста, включите любые ссылки, которые вы нашли, чтобы мы могли ответить на ваш вопрос. что такое стек, на который вы ссылаетесь? Я полагаю, вы имеете в виду этот CLISP? (как тег, так, наверное) Под источниками вы подразумеваете его исходный код? если да, то зачем вам это? или вы имеете в виду спецификации языка, такие как это? или вы имеете в виду какие-либо общие фрагменты исходного кода lisp для изучения? здесь конкретный вопрос, как переписать ваш код Python как код Common Lisp?   -  person Will Ness    schedule 18.04.2020
comment
Как бы вы написали код Python в формате CLISP? Я пытался, но продолжаю получать ошибки. Ваше здоровье.   -  person johnny_trfc    schedule 18.04.2020
comment
наблюдение за вашей попыткой определенно поможет ответить. пожалуйста, включите его в свой пост.   -  person Will Ness    schedule 18.04.2020


Ответы (1)


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

def f(x):
    if (x <= 1/2):
        return 2 * x
    else:
        return (2 * x) - 1

x = 1/10
for i in range(80):
    print(x)
    x = f(x)

В Python 2 это печатает только нули, потому что вы не работаете с рациональными числами , но просто выполняя целочисленное деление, которое усекается до нуля (с последующим умножением на 2). В Python 3 результатом будет ряд чисел с плавающей запятой, которые сходятся к 1.0, потому что числа с плавающей запятой приблизительны (спасибо @ex nihilo).

CLISP — это одна конкретная реализация стандарта Common Lisp среди прочих (в произвольном порядке Lispworks, ECL, SBCL, Allegro CL, Clozure Common Lisp, ABCL, CLASP, ...). Обычно Common Lisp обозначается аббревиатурой CL, а иногда просто Lisp (это несколько спорное мнение), по той причине, что другие ветви семейства решили следовать совершенно другим философиям и назывались по-разному (Scheme, Clojure или даже Julia). Однако все они принадлежат к «семье Лиспов».

Если под CLISP вы подразумеваете Common Lisp, то идиоматический способ кодирования будет таким:

(defun f (x)
  (if (<= x 1/2)
      (* 2 x)
      (1- (* 2 x))))

(loop
   for i below 80
   for x = 1/10 then (f x)
   collect x)

Это оценивается как(*):

(1/10 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5)

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

from fractions import Fraction

def f(x):
    if (x <= Fraction(1, 2)):
        return 2 * x
    else:
        return (2 * x) - 1

x = Fraction(1,10)
r = list()
for i in range(80):
    r.append(x)
    x = f(x)

В результате получился список:

[Fraction(1, 10), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5)]

(*), но

(loop
   for i below 80
   for x = 0.1 then (f x)
   collect x)

оценивает

(0.1 0.2 0.4 0.8 0.6 0.20000005 0.4000001 0.8000002 0.6000004 0.20000076
 0.40000153 0.80000305 0.6000061 0.2000122 0.4000244 0.8000488 0.60009766
 0.20019531 0.40039063 0.80078125 0.6015625 0.203125 0.40625 0.8125 0.625 0.25
 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0)

и преобразование этого обратно в рациональные числа показывает, что это

(13421773/134217728 13421773/67108864 13421773/33554432 13421773/16777216
 5033165/8388608 838861/4194304 838861/2097152 838861/1048576 314573/524288
 52429/262144 52429/131072 52429/65536 19661/32768 3277/16384 3277/8192 
 3277/4096 1229/2048 205/1024 205/512 205/256 77/128 13/64 13/32 13/16 5/8 
 1/4 1/2 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 
 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 
 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1)

Действительно, если мы используем 13421773/134217728 в качестве начальной точки цикла, результирующая последовательность будет точно такой же.

person coredump    schedule 18.04.2020
comment
Удивительный! Спасибо :). Как вы развивали свои навыки CLISP? В настоящее время у меня есть книга Питера Сейбеля «Practical Common Lisp». Есть ли у вас какие-либо рекомендации, пожалуйста? Похоже, мои усилия по написанию функции были близки, но раздел (‹= x 1/2) у меня был наоборот. Очень признателен! - person johnny_trfc; 18.04.2020
comment
Спасибо, есть много книг, учебников, я думаю, что у клики есть хорошие ресурсы для начинающих: cliki.net /Lisp%20books В основном я много читал и практиковался в написании небольших и средних программ. CL не был моим первым языком, который я выучил, ваш опыт может отличаться. - person coredump; 18.04.2020
comment
но просто выполнение целочисленного деления, которое усекается до нуля -- в Python 2 это было бы целочисленное деление, но в Python 3 / выполняет деление с плавающей запятой и дает float, когда его операнды являются целыми числами; Код OP будет работать под любым из них. - person ad absurdum; 19.04.2020
comment
@exnihilo Спасибо, я забыл, что в обеих версиях поведение было разным, я отредактировал ответ. - person coredump; 19.04.2020
comment
это оказалось миленькой штуковиной, да. Спасибо за ответ. - person Will Ness; 19.04.2020