‮Сдвиг по фазе (kincajou) wrote,
‮Сдвиг по фазе
kincajou

Ботанизм-програмизм (4).

Сварганил оператор CASE, на сей раз попытался добавить "синтаксический сахар" (пока не очень удачно вышло, но уже кое-что):

CASE-TEST: ( CASE "Apple" ( ( ( < 5 )
 ( FORMAT "Less than 5~%" )
 )
 ( ( = 5 )
 ( FORMAT "Equals 5~%" )
 )
 ( ( > 5 )
 ( FORMAT "Greater than 5~%" )
 )
 ( ( = "Apple" )
 ( FORMAT "It's an apple!~%" )
 )
 )
 ( FORMAT "I dont know what is it~%" )
 )


Вычисление этого кода печатает "It's an apple!".

В общем виде структура такая:
( CASE (expr) 
  ( 
    ( ( cond-p-1 ) ( instr-1 ) )
    ( ( cond-p-2 ) ( instr-2 ) ) 
   ..
    ( ( cond-p-n ) ( instr-n ) )
  )
  ( when-not-of-it-all-instr )
)

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

( > 5 expr )

Что даёт результат, совершенно противоположный очевидно-ожидаемому: например, если expr было равно 2, то записав условие в виде ( > 5 ) мы будем ожидать, что этот предикат НЕ сработает, в то время как в реальности ( > 5 2 ) возвращает, очевидно, T и далее вызывается связанный с этим условием код.

Очевиден так же и метод обхода, хоть он и немного громоздкий - в качестве предикатов для неких "временных", нужных только в этом месте, условий, надо использовать лямбды! Т.е. на месте ( > 5 ) надо записать как-то так:

(apply ( lambda (x) ( > x 5 ) ) )


Этот код должен работать правильно. И сейчас я это проверю...

...
????
!!!!
...

( CASE "Apple" ( ( ( = 5 )
 ( FORMAT "Equals 5~%" )
 )
 ( ( APPLY ( LAMBDA ( X )
 ( > X 5 )
 )
 )
 ( FORMAT "Less than 5~%" )
 )
 ( ( APPLY ( LAMBDA ( X )
 ( < X 5 )
 )
 )
 ( FORMAT "Greater than 5~%" )
 )
 ( ( APPLE-P )
 ( FORMAT "It's an apple!~%" )
 )
 )
 ( FORMAT "I dont know what to do with ~a~%" $ )
 )

It's an apple!


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

APPLE-P это как раз предикат, который проверяет равенство своего аргумента строке "Apple".
$ - это локальный символ, которому присваивается вычисленное значение expr. Вот что будет, если тот же CASE запустить с чем-то, чего он не знает:

( CASE "Pineapple" ( ( ( = 5 )
 ( FORMAT "Equals 5~%" )
 )
 ( ( APPLY ( LAMBDA ( X )
 ( > X 5 )
 )
 )
 ( FORMAT "Less than 5~%" )
 )
 ( ( APPLY ( LAMBDA ( X )
 ( < X 5 )
 )
 )
 ( FORMAT "Greater than 5~%" )
 )
 ( ( APPLE-P )
 ( FORMAT "It's an apple!~%" )
 )
 )
 ( FORMAT "I dont know what to do with ~a~%" $ )
 )

I dont know what to do with "Pineapple"


РАБОТАЕТ!

Правда, это совсем не то же самое, что CASE в Common Lisp. И не совсем COND. Переименовал в "SELECTOR", пусть будет.. и тут же, пока горячо, накропал более привычный и почти стандартный CASE. Отличие только одно - не используется слово "otherwise", вместо этого код для "никакого" условия вынесен как бы в отдельную ветку. Вот:
( CASE "Beta" ( ( "Kenobi" "Jedi" )
 ( ( 5 99 1024 )
 "Kinda integer" )
 ( ( "Alpha" 1 "Beta" )
 ( FORMAT "UncommonLisp is awesome!~%" )
 )
 )
 ( FORMAT "I dont know what to do with ~a~%" $ )
 )

UncommonLisp is awesome!
Tags: uncommon lisp
Subscribe

  • Говорят, в Томске маньяка поймали.

    ... но явно не того. Пойманный -- какой-то бывший мент, а должен быть писатель, по образованию физик-теоретик, в космонавтике, так сказать,…

  • Кого бережёт милиция?..

    ..то есть полиция, но смысл от этого не меняется. Короче говоря, сегодня утром, по пути на работу, стал свидетелем странной ситуации. А именно,…

  • Молвят, сегодня случилось CME

    Coronal Mass Ejection - весьма редкое событие, и вот оно, пожалста-неждали! Есть ненулевой риск веерных отключений искричества и прочих…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments