Уроки ЛІСП
Урок 1 (http://lingvoforum.net/index.php/topic,44964.0.html)
Урок 2 (http://lingvoforum.net/index.php/topic,45581.0.html)
Обговорення (http://lingvoforum.net/index.php/topic,44728.0.html)
Тут дехто цікавився сабжем, тож думаю організувати їх (якщо бажаючих набереться вдосталь і у мене буде час).
Отже, питання: чи справді це комусь цікаво? Лісп — далеко не найпопулярніша й не найюзабельніша мова, яка не надто часто використовується на практиці, хоча й «розширює свідомість», «покращує загальний рівень програміста» і т.п. Хоча, по-моєму, цю гілку мов просто не оцінили як слід.
Питання номер два: що саме вчити? Scheme, Clojure, Common Lisp? З останнім я знайомий лише поверхнево, тому для організації уроків мені самому доведеться його вчити. Scheme — мова, на прикладі якої простіше зрозуміти, що таке лісп (у світі ліспів вона займає приблизно таке ж місце, як Pascal — у світі алгоритмічних мов). Clojure — молода мова, місцями досить-таки сира, але для практичного застосування я б вибрав саме її, хоча там є безліч відмінностей від «типового ліспа», не вистачає концептуальної довершеності і т.п.
Питання номер три: в якому напрямку розвивати уроки? Що краще — ознайомлення з мовою на прикладі практичних задач, огляд якомога більшої кількості можливостей мови, щось іще? Взагалі, як краще будувати урок? Я раніше не вів уроків, тому досвіду у мене обмаль.
А чому ви вирішили не у вашому блозі?
Гуглятор правильно перевёл?
Цитата: arseniiv от февраля 10, 2012, 22:12
А чому ви вирішили не у вашому блозі?
Гуглятор правильно перевёл?
Тому що блога на ЛФ не маю — мені вистачає й українського розділу на форумі.
Цитата: Python от февраля 10, 2012, 22:17
Тому що блога на ЛФ не маю
:o Мені здавалося що він був! (?)
Не було (не рахуючи однієї теми в блорумі). Ще є блог на домашньому комп'ютері, але він без коментарів.
А що скажете по темі — якісь побажання до уроків будуть? До речі, скачав hugs, чекаю уроків Haskell'а ;)
Мені цікаво.
З гуглятором ніби все ОК — явних помилок не бачу
Цитата: Python от февраля 10, 2012, 21:45
Отже, питання: чи справді це комусь цікаво?
Так.
Я давно хочу повчити Лісп, але все якось не... А тут була б нагода.
Цитата: Python от февраля 10, 2012, 21:45Питання номер два: що саме вчити? Scheme, Clojure, Common Lisp? З останнім я знайомий лише поверхнево, тому для організації уроків мені самому доведеться його вчити. Scheme — мова, на прикладі якої простіше зрозуміти, що таке лісп (у світі ліспів вона займає приблизно таке ж місце, як Pascal — у світі алгоритмічних мов). Clojure — молода мова, місцями досить-таки сира, але для практичного застосування я б вибрав саме її, хоча там є безліч відмінностей від «типового ліспа», не вистачає концептуальної довершеності і т.п.
Вибирайте те, що Вам самому подобається. Так більше шансів, що уроки ми взагалі побачимо. ;D
Цитата: Python от февраля 10, 2012, 21:45
Питання номер три: в якому напрямку розвивати уроки? Що краще — ознайомлення з мовою на прикладі практичних задач, огляд якомога більшої кількості можливостей мови, щось іще? Взагалі, як краще будувати урок? Я раніше не вів уроків, тому досвіду у мене обмаль.
Меня здається, що практичних задач варто додати, правда, не надто великих. З описаннями можливостей мови проблем немає. Основна проблема — навчитися писати ідіоматичні програми, які ці можливості використовують.
ЦитироватьВибирайте те, що Вам самому подобається.
Так ось я і не знаю, що краще. Сам я починав зі Scheme, і, мені здається, на прикладі цієї мови легше зрозуміти базові концепції лісп-подібних мов. Але я з самого початку орієнтувався на лісп для JVM, тому перехід до Clojure був цілком закономірним. В принципі, можемо розглянути й обидві мови в порівнянні, а далі зосередитись на якійсь одній із них.
Зараз пишу в блокноті другий урок. Ще трохи базового синтаксису (функції, вибір, змінні). Багато не надто цікавого матеріалу (цікавіше буде потім) — не знаю, чи треба це комусь, чи ті, хто цікавиться ліспом, вже його якось самі засвоїли без моєї допомоги.
Взагалі, для чого вам той лісп? Чого ви від нього очікуєте? Спробую розвивати уроки в відповідному напрямку.
Цитата: Python от февраля 24, 2012, 00:28
Взагалі, для чого вам той лісп?
Для себе. Зрозуміло, що писати комерційні програми я на ньому навряд чи буду, це не мейнстрім, тому кому він тут потрібен?
А ось коли писати програмки для власного користання, то можна писати їх будь-якою мовою.
Цитата: Python от февраля 24, 2012, 00:28
Чого ви від нього очікуєте?
Було б дуже непогано вивчити Схему і мати можливість вбудувати собі скриптову мову з мацзяном і гейшами в будь-яку програму з мінімальним overhead. Коли я дивлюся на розміри Tiny Scheme, в мене слюни течуть... Хотілося б її опанувати.
Хоч, я так зрозумів, Ліспи ви використовуєте і для більш практичних мет. Теж було б цікаво подивитися на якийсь приклад; довідатися, наприклад, чим воно зручніше того ж Python'а... ::)
Хочу продовження...
А можно здесь кого-нибудь попросить (не меня) складывать ссылочки на темы? А то я и не знал, что уже есть второй.
ЛІСП: урок перший (http://lingvoforum.net/index.php/topic,44964.0.html)
ЛІСП: урок другий (http://lingvoforum.net/index.php/topic,45581.0.html)
Upd. Ой, ссылочки-то есть в первом уроке. А у меня в непрочитанных не отразилось! :-\
На початку кожного уроку буде зміст з посиланнями на всі уроки. Якщо хочете, можу ще кидати в цю тему посилання на нові уроки.
Хочу! Спасибо.
Уроки=чари, а не лекція! Не врікайте LISPа, він й так на ладан диха! ;)
1) У школі — уроки, а не лекції. Всі вчительки — відьми?
2) Ви недооцінюєте могутність ліспа. Це ж вам не фортран якийсь.
Цитата: Python от марта 2, 2012, 19:13
1) У школі — уроки, а не лекції. Всі вчительки — відьми?
ЦитироватьРосійсько-український словник 1930р. (О. Ізюмов)
Урок –
1) (задание) завда́ння, -ння;
2) (школьный у.) ле́кція, -ії;
3) (назидание) нау́ка, -ки. [2]
Російсько-український словник ділової мови 1930р. (М. Дорошенко, М. Станиславський, В. Страшкевич)
Урок;
1) (лекция) – ле́кція чого́; (занятие) – година чого́;
2) (задание) – завда́ння, призна́чена, визначена робо́та, но́рма вироблення, но́рма виробу;
3) (назидание) – нау́ка. [5]
Російсько-український словник правничої мови 1926р. (В. І. Войткевич-Павлович, Г. Д. Вовкушівський та інші)
Урок – лекція, година, (руссизм) урок. -ки (учение) – наука; наперед загадана робота, загад, (руссизм) урок. [6]
Исполнять, исполнить – виконувати, виконати (АЮЗР, 6, І, 343; КМ); відбувати, відбути (повинність). -нить волю – вволити (вчинити) волю чию. -нить поручение – виконати доручення. -щий обязанности, должность – заступник; наказний. -щий должность судьи – наказний суддя. -нить слово – додержати слова. -нять служебные обязанности – виконувати службові повинності (обов'язки); (администр.) держати уряд (КМ). -нять урок – поробити призначену роботу. -ниться – справдитися. [6]
У школі теж лекція. :)
Так то ще в роки дитинства наших дідів було. Та й то, не факт, що справді було так.
А вчительки називалися професорками!
вчити=приручати=приборкувати
рrоfitеоr=відкрито говорити
Цитата: Sirko от марта 2, 2012, 18:57
Уроки=чари, а не лекція!
Сірко, Ви можете зайнятися перекладом цих
уроків лекцій з української на українську. ;D
Ось у мене таке питання. І в Racket, і в Kawa є можливість вибирати різні мови програмування... В Racket це
#lang racket. Навіщо?
ЦитироватьWriting definitions outside of a module leads to bad error messages, bad performance, and awkward scripting to combine and run programs. The problems are not specific to racket; they're fundamental limitations of the traditional top-level environment, which Scheme and Lisp implementations have historically fought with ad hoc command-line flags, compiler directives, and build tools. The module system is designed to avoid these problems, so start with #lang, and you'll be happier with Racket in the long run.
Які саме проблеми вирішує
#lang racket?
З racket я справи не мав, тому не впевнений, чи зможу дати точну відповідь. Наскільки я можу зрозуміти, в процитованому абзаці йдеться про різницю між синтаксичними конструкціями #lang і (module) — у другому випадку, всі описи модуля мають бути всередині дужок, тоді як #lang дозволяє дещо спростити синтаксис файла з модулем.
http://docs.racket-lang.org/guide/Module_Syntax.html
Пробую щось вчити. Взяв Racket, бо в нього, як мені здалося, достатньо симпатична бібліотека (правда, в Kaw'и та Clojur'и явова бібліотека також симпатична, але ж уся документація для Jav'и).
Ось програмка, яка виводить ієроглифи з надписом над ними. Чи все я роблю правильно? Що можна поміняти, щоб зробити цю програму більш лісповою?
(http://www.imageup.ru/img280/927427/test.png)
#lang racket/gui
(define (yale-to-vector yale)
(apply vector (regexp-split #px"[[:space:]]+" yale)))
(define target (make-bitmap 150 50))
(define dc (new bitmap-dc% [bitmap target]))
(define hanzi-font (make-object font% 24 "Microsoft JhengHei" 'roman 'normal))
(define yale-font (make-object font% 8 "Tahoma" 'roman 'normal))
(define (draw-one-hanzi hanzi yale x y)
(send dc set-font hanzi-font)
(define-values (hz-width hz-height hz-desc hz-asc) (send dc get-text-extent hanzi))
(send dc draw-text hanzi x (+ y 10))
(send dc set-font yale-font)
(define-values (y-width y-height y-desc y-asc) (send dc get-text-extent yale))
(send dc draw-text yale (+ x (/ (- hz-width y-width) 2)) y)
(+ x hz-width))
(define (draw-hanzi-string hanzi yale x y)
(define len (string-length hanzi))
(define yale-vector (yale-to-vector yale))
(let loop ([i 0] [current-x 5])
(cond [(< i len)
(loop (+ i 1)
(draw-one-hanzi (string (string-ref hanzi i))
(vector-ref yale-vector i)
current-x
y))])))
(draw-hanzi-string "晚安" "máahn ōn" 5 0)
target ;щоб вивести картинку в REPL-і
(send target save-file "C:\\test.png" 'png)
ЦитироватьЩо можна поміняти, щоб зробити цю програму більш лісповою?
Замість define краще використовувати let (особливо для змінних всередині функцій).
А почему бы не перевести эти уроки в этот раздел: http://lingvoforum.net/index.php/board,157.0.html
Цитата: Python от апреля 19, 2012, 13:56
ЦитироватьЩо можна поміняти, щоб зробити цю програму більш лісповою?
Замість define краще використовувати let (особливо для змінних всередині функцій).
Чому?
let добавляє зайву скобку в кінці, а їх і так там багато. :-[
Тай ніби то
define усередені функцій працує локально, отож чому його треба позбігати?
ЦитироватьА почему бы не перевести эти уроки в этот раздел: http://lingvoforum.net/index.php/board,157.0.html
Мені, маючи модераторські повноваження в цьому розділі, зручніше вести їх тут. Крім того, мови програмування серед уроків людських мов виглядають трохи дивно :)
Цитата: Demetrius от апреля 19, 2012, 15:28
Цитата: Python от апреля 19, 2012, 13:56
ЦитироватьЩо можна поміняти, щоб зробити цю програму більш лісповою?
Замість define краще використовувати let (особливо для змінних всередині функцій).
Чому? let добавляє зайву скобку в кінці, а їх і так там багато. :-[
Тай ніби то define усередені функцій працує локально, отож чому його треба позбігати?
Можна й так, в принципі. Але питання стосувалось лісп-вейності, а внутрішнє define є суто схемівським прийомом — у Clojure, наприклад, внутрішнє def чи defn працює як глобальне.
Цитата: Python от апреля 19, 2012, 15:42Можна й так, в принципі. Але питання стосувалось лісп-вейності, а внутрішнє define є суто схемівським прийомом — у Clojure, наприклад, внутрішнє def чи defn працює як глобальне.
Зрозуміло. А я вже подумав, що причина в тому, що let можна скопіпастити куди завгодно, а define можепогризтися з іншими ідентифікаторами...
До речі, я зрозумів, у чому справжня перевага let'ів над локальними define'ами: змінні, створені за допомогою define, можна set!. А let'и не можна, отож компілятори краще оптимізують та менше шансів щось наплутати.
Попробував собі написати Клоџурне
doto для Kaw'и. Я все правильно роблю?
; Clojure-like doto macro for Kawa scheme
(define-syntax doto
(syntax-rules ()
((_ object (method . args))
(let ((obj object))
(method obj . args)
obj))
((_ object method1 method2 ...)
(begin (doto object method1)
(doto object method2 ...)))))Викликається так:
(*:show (doto
(javax.swing.JFrame)
(*:set-title "Hello world!")
(*:set-size 300 50)))Виклик
*:show не можна поставити останнім аргументом у
doto, адже тоді
doto поверне JFrame, Kawa попробує вивести його у REPL і все зависне.
ЦитироватьДо речі, я зрозумів, у чому справжня перевага let'ів над локальними define'ами: змінні, створені за допомогою define, можна set!. А let'и не можна, отож компілятори краще оптимізують та менше шансів щось наплутати.
Технічно, з let-змінними set! теж працює (принаймні, в SISC і KAWA). Хоча для Clojure це справді так — let створює незмінювану локальну змінну, тоді як def може працювати як define й set!, перевизначаючи глобальну змінну.
ЦитироватьПопробував собі написати Клоџурне doto для Kaw'и. Я все правильно роблю?
Схоже, що не все. Судячи з усього, воно розписує згаданий приклад у щось назразок
(*:show
(begin
(let ((obj (javax.swing.JFrame)))
(*:set-title obj "Hello world!"))
(let ((obj (javax.swing.JFrame)))
(*:set-size obj 300 50))))
Таким чином, генеруються два фрейми, з яких відображається лише останній (з заданим розміром, але без заданого заголовку). З цієї ж причини виникає проблема з show, якщо його розмістити в doto.
Цитата: Python от апреля 23, 2012, 13:30
Схоже, що не все. Судячи з усього, воно розписує згаданий приклад у щось назразок
...
Таким чином, генеруються два фрейми, з яких відображається лише останній (з заданим розміром, але без заданого заголовку).
Гм... А так:
; Clojure-like doto macro for Kawa scheme
(define-syntax doto
(syntax-rules ()
((_ object (method . args))
(let ((obj object))
(method obj . args)
obj))
((_ object method1 method2 ...)
(let ((obj object))
(doto obj method1)
(doto obj method2 ...)))))Ніби то так воно працює правильно. Так добре?
Цитата: Python от апреля 23, 2012, 13:30З цієї ж причини виникає проблема з show, якщо його розмістити в doto.
Ні, проблема з
*:show викликана недоробленим графічним інтерфейсом Kaw'и. ;D
Цитата: Python от апреля 23, 2012, 13:21
Технічно, з let-змінними set! теж працює (принаймні, в SISC і KAWA).
Гм... Тоді навіщо в схемі
let взагалі? :what:
Можливо. Я користуюсь стандартною консоллю замість кавівського GUI, і нічого схожого на зависання не помітив.
Цитата: Demetrius от апреля 23, 2012, 13:56
Цитата: Python от апреля 23, 2012, 13:21
Технічно, з let-змінними set! теж працює (принаймні, в SISC і KAWA).
Гм... Тоді навіщо в схемі let взагалі? :what:
begin і let по-різному взаємодіють з define всередині.
Цитата: Python от апреля 23, 2012, 14:00
Можливо. Я користуюсь стандартною консоллю замість кавівського GUI, і нічого схожого на зависання не помітив.
Зависання пов'язане саме з графічним інтерфейсом. Коли написати
(javax.swing.JButton text: "Push me!"), в графічному інтерфейсі появляється не опис об'єкта, а кнопка. Але з вікнами у цієї можливості проблема: якщо написати
(javax.swing.JFrame title: "I am a bug"), усе зависне.
ЦитироватьЗависання пов'язане саме з графічним інтерфейсом. Коли написати (javax.swing.JButton text: "Push me!"), в графічному інтерфейсі появляється не опис об'єкта, а кнопка. Але з вікнами у цієї можливості проблема: якщо написати (javax.swing.JFrame title: "I am a bug"), усе зависне.
Тоді зрозуміло. Гадаю, цю проблему можна обійти, обгорнувши все в begin з якимсь пустим виразом після дії з фреймом.
Цитата: Python от апреля 23, 2012, 14:07
Тоді зрозуміло. Гадаю, цю проблему можна обійти, обгорнувши все в begin з якимсь пустим виразом після дії з фреймом.
Ну, винесення
(*:show ...) — це якраз спосіб обійти цю проблему. ;D
До речі, мій макрос гігієнічний? :what:
Цитата: Demetrius от апреля 23, 2012, 14:11
До речі, мій макрос гігієнічний? :what:
На жаль, із цим «гігієнічним» ситаксисом важко зрозуміти, що він насправді робить гігієнічно, а що ні. З defmacro в поєднанні з gensym можна, принаймні, побачити неозброєним оком, що там відбувається насправді.
Провів невеликий тест. Ніби гігієнічний.
#|kawa:22|# (define obj 5)
#|kawa:24|# (doto 6 (display) (begin (display obj)))
6 5 6
О, дякую!
Я вже собі наступну вправу придумав: думаю написати макрос, який імітує клоџурний import. Але, думаю, тут syntax-rules не підійде.