LINUX.ORG.RU

Где ещё есть print/read как в Common Lisp с *print-readably* ?

 ,


0

4

Вот смотрю Julia

Julia:

julia> Int8[[1 2] [3 4]]
1×4 Array{Int8,2}:
 1  2  3  4
Это круто, конечно, но ведь я уже не зачитаю то, что напечаталось.

Смотрю Dylan: вроде есть что-то похожее на лисповый reader.

Смотрю Io: вроде есть что-то http://iolanguage.org/reference/index.html

  Io> Object clone do(x:=1) serialized
  ==> Object clone do(
  	x := 1
  )

Однако неясно, есть ли что-то подобное *print-readably* Соответственно, вопрос всем: где оно есть, где лично вы им пользовались?

★★★★★

А в чем проблема с Io? тебе выдан исходник, ты можешь его прочитать, любой другой объект может его прочитать, и сделать с ним что пожелает? Что еще надо?

portquest2016
()

между прочим, Io может делать с кодом то, что твоим лиспам и не снилось, он может ходить по коду прямо в рантайме, с места вызова, взад-вперед.

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

Во. Это лучше, чем постить всякую философию. Ты можешь приготовить обучающее видео на эту тему для туповатых и выложить его на Ютьюб?

А в чем проблема с Io? тебе выдан исходник, ты можешь его прочитать, любой другой объект может его прочитать, и сделать с ним что пожелает? Что еще надо?

Проблема в том, что я не вижу ни поста в блоге об этом, ни примера. Можешь ткнуть в конкретную ссылку?

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

не, никакое видео я делать не буду, мне за это не платят, а если бы и платили, мое время слишком дорого. Я обсуждаю лишь то, что мне самому интересно.

Можешь ткнуть в конкретную ссылку?

Я ни фига не понял, какая ссылка тебе нужна? Ты получил код, делай с ним все что хочешь, что нужно то?

А в целом есть reference manual на офсайте, он умещается на одной странице, прочитав его можно начинать программировать. Io — очень минималистичный язык

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

Я не понимаю, что значит «ходить взад-вперёд». В лиспе удобно делать всякие конфиг-файлы. Заводишь несколько структур данных, print-ом сохраняешь в файл, а потом read-ом считываешь. При этом файл получается вполне читаемый, примерно такой:

#S(конфигурация
   :общие-параметры 
    (:ip 127.0.0.1
     :port 6556
    )
   :модули (
      #S(модуль
         :имя "python"
         :исполняемый-файл "python" 
        )
      #S(модуль
         :имя "perl"
        )))
Соответственно, можно генерировать код и тоже сохранять его в файл, затем считывать оттуда. Типичный пример - .emacs .

Ещё в лиспе можно так сохранять циклические графы, а не только деревья. Ещё есть «нечитаемые объекты», например #<OBJECT my-object 1324123123>, которые нельзя прочитать - и функция read на них обругается, но тем не менее более-менее понятно, что за объект напечатан.

Вот такой скромный набор возможностей я считаю необходимым в любом языке, автор которого действительно осилил лисп и утверждает, что данный язык восходит к лиспу как к одному из «корней».

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

Если тебя тяготит материальная нужда, мы можем это обсудить частно, как с тобой связаться?

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

нет меня не тяготит нужда, но я не занимаюсь х*ней. Обычно она тяготит как раз тех, кто ей занимается, тут обратная связь присутствует.

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

Все что ты перичислил, это какие то кружева для девочек. Надо не гордится, а стыдится, что серьезный язык похож на свистящую и пердящую дешовку.

Я не понимаю, что значит «ходить взад-вперёд»

tst := method(
  call message previous println
)

foo := Object clone do(
  bar := getSlot("tst")
)

foo bar // в рантайме видит откуда вызвана, печатает foo bar

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

то данный язык восходит к лиспу как к одному из «корней».

Он, кстати, говорил о влиянии не этого лиспа, про который ты тут чешешь, а старые лиспы, где код был доступен в рантайме, но в основе своей Io — чистейший ООП язык, исходный код там — это всего лишь представление.

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

Соответственно, можно генерировать код и тоже сохранять его в файл, затем считывать оттуда. Типичный пример - .emacs .

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

«нечитаемые объекты», например #<OBJECT my-object 1324123123>, которые нельзя прочитать

А вот это уже чем то анальным попахивает

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

Всё равно я не понял. Ты имеешь в виду, что он посмотрел вверх по стеку и увидел, откуда его вызвали? Если это, то меня это не интересует. Меня интересует, как практически осуществляется гомоиконность. Где квазицитаты? Как сделать файл инициализации, подобный тому, к-рый я привёл.

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

Меня интересует, как практически осуществляется гомоиконность

что ты под «практическим осуществлением» подразумеваешь, но в Io синтаксическая структура представлена примерно вот так <message> <message> <message> <message>...кроме сообщений есть еще несколько операторов, которые разворачиваются препроцессором. Например, :=, ::=, = являются операторами, к сожалению.

Где квазицитаты?

Этот уродливый костыль сделан для языков, где нет ленивых функций, в нормальных ЯП он не нужен, в тч и в нормальных лиспах.

Как сделать файл инициализации, подобный тому, к-рый я привёл

просто запиши в файл код, а затем в рантайме считай его и выполни. Детский сад какой-то

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

Этот уродливый костыль сделан для языков, где нет ленивых функций, в нормальных ЯП он не нужен, в тч и в нормальных лиспах.

Квазицитата - это способ формирования данных из двух частей, доступных в разное время, с явным представлением того, какая часть будет взята в какое время. При чём тут ленивые функции?

просто запиши в файл код, а затем в рантайме считай его и выполни.

Пример сохранения и чтения конфигурации в лиспе выглядит так:

; сохранение
(with-open-file (ou "~/.config" :direction :output 
                    :if-does-not-exist :create
                    :if-exists :supersede)
  (print *configuration* ou))
; восстановление 
(with-open-file (ou "~/.config")
  (setf *configuration* (read ou)))
Как это будет выглядеть в io?

den73 ★★★★★
() автор топика

снова одиозный дениска вылез

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

При чём тут ленивые функции?

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

Как это будет выглядеть в io?

Я не понял что делает этот код. Похоже на какую то банальщину, типа записи-чтения-выполнения из файла. Пусть будет так


config := Object clone do(
  foo := 1
  bar := 2
)

File with("config") do(open; write(config serialized); close)

config2 := doFile("config")
config2 foo print #>>>> 1

В любом случае, нет ничего такого, что можно сделать в лиспе и нельзя в Io

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

Я не понял что делает этот код.

Зачем тогда рассуждаешь о Лиспе, если даже такой примитивизм не можешь прочитать? :-) Лол :-)

В любом случае, нет ничего такого, что можно сделать в лиспе и нельзя в Io

В Лиспе можно сложить первые миллиард натуральных чисел за 0,7 секунды :-) А в Io за такое время этого сделать никак нельзя :-)

(time (loop for i fixnum from 0 to 1000000000 sum i fixnum))
(LOOP FOR I FIXNUM FROM 0 TO 1000000000 SUM I FIXNUM)
took 749,626 microseconds (0.749626 seconds) to run.

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

Ух ты, а на асме еще круче.

А, ну вот и всё :-) Тебе до что до асма? :-) Для тебя важно то, что на Io нельзя :-) Лол :-)

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

О, человек-улыбка. А в компил-тайме можно? На макросах, например?

Можно :-)

(defmacro define-sum-special (num)
  (let ((s (multiple-value-bind (sym)
               (intern (format nil "*SUM-~A*" num)) sym)))
    `(defparameter ,s (loop for i fixnum from 0 to ,num sum i fixnum))))

CL-USER> (define-sum-special 10)
*SUM-10*
CL-USER> (define-sum-special 100)
*SUM-100*
CL-USER> (define-sum-special 1000)
*SUM-1000*
CL-USER> (define-sum-special 10000)
*SUM-10000*
CL-USER> (define-sum-special 100000)
*SUM-100000*
CL-USER> *sum-10*
55
CL-USER> *sum-100*
5050
CL-USER> *sum-1000*
500500
CL-USER> *sum-10000*
50005000
CL-USER> *sum-100000*
5000050000
anonymous
()
Ответ на: комментарий от anonymous

Здорово, спасибо. Ждем аналога на io.

Только вот меня смущает отсутствие unquote перед loop. Макрос разве не вернёт его без выполнения? Точно не в рантайм уйдет? Я не знаток лиспа, впрочем, но мне интересно разобраться.

И да, если в тред зайдут знатоки scheme, скажите, на гигиенических макросах ведь такое не сделаешь? Они мне показались просто умной постановкой кода, я не понял как через define-syntax вычислять что-то в компилтайм. Но я не исключаю, что я дурак.

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

Только вот меня смущает отсутствие unquote перед loop.

А, ну если тебе прям сумма нужна в компайл-тайм, то вот маленький фикс :-)

(defmacro define-sum-special (num)
  (let ((s (multiple-value-bind (sym)
               (intern (format nil "*SUM-~A*" num)) sym))
        (sum (loop for i from 0 to num sum i)))
    `(defparameter ,s ,sum)))
anonymous
()
Ответ на: комментарий от Weres

Только вот меня смущает отсутствие unquote перед loop. Макрос разве не вернёт его без выполнения? Точно не в рантайм уйдет? Я не знаток лиспа, впрочем, но мне интересно разобраться.

для тех, кто смущается придуман macroexpand-1 (чтобы знали).

вот выыод в РЕПЛ (чуть раздвинул строки для читаемости):

CL-USER> (defmacro define-sum-special (num)
           (let ((s (multiple-value-bind (sym)
                        (intern (format nil "*SUM-~A*" num)) sym)))
             `(defparameter ,s (loop for i fixnum from 0 to ,num sum i fixnum))))

DEFINE-SUM-SPECIAL

CL-USER> (macroexpand-1 '(define-sum-special 10))

(DEFPARAMETER *SUM-10*
  (LOOP FOR I FIXNUM FROM 0 TO 10
        SUM I FIXNUM))
T

CL-USER> (defmacro define-sum-special (num)
           (let ((s (intern (format nil "*SUM-~A*" num))))
             `(defparameter ,s ,(loop for i fixnum from 0 to num sum i fixnum))))

WARNING: redefining COMMON-LISP-USER::DEFINE-SUM-SPECIAL in DEFMACRO
DEFINE-SUM-SPECIAL

CL-USER> (macroexpand-1 '(define-sum-special 10))

(DEFPARAMETER *SUM-10* 55)
T

CL-USER> 

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

расскажи, о лисп-гуру, смысл использования multiple-value-bind с 1 (ОДНИМ!) параметром.

Чтоб подчеркнуть, что INTERN возвращает 2 значения :-)

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

да хоть 50. в нём нет никакого смысла, кроме запутывания кода

Раз ты обратил внимание, значит моё намерение сработало :-) Я на твой вопрос ответил? :-) Ответил :-) А то, что тебя там что-то запутывает - это не мои проблемы :-)

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

Раз ты обратил внимание, значит моё намерение сработало

ТАКАЯ глупость сразу бросается в глаза

Я на твой вопрос ответил?

это был сарказм. видимо ты его не испытывал

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

ТАКАЯ глупость сразу бросается в глаза
это был сарказм. видимо ты его не испытывал

Как же вас таких много :-) Лол :-)

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

И да, если в тред зайдут знатоки scheme, скажите, на гигиенических макросах ведь такое не сделаешь? Они мне показались просто умной постановкой кода, я не понял как через define-syntax вычислять что-то в компилтайм.

если на чисто define-syntax то

(define-syntax (yoba stx)
  (syntax-case stx ()
    [(_ num) #`#,(for/sum ([i (syntax->datum #'num)]) i)]))
или в racket:
(define-simple-macro (yoba num:nat)
  #:with res #`#,(for/sum ([i (syntax->datum #'num)]) i)
  res)

anonymous
()
Ответ на: комментарий от portquest2016
config2 foo print 
#>>>> 1

Ты это имел в виду? Тогда да, это то, что я хотел, спасибо за пример.

при том, что объект, который получает сообщение сам может решить, чо ему выполнять, а что нет. Емнип, лиспы, где есть фэкспры вообще не используют квазицитирование
Есть такой процесс интересный, называется отладка. И вот из-за него лиспы с фэкспрами забыты. Хотя макросы в CL на самом деле в какой-то степени являются фэкспрами.

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

что обкруг чего вертится:

так что в этой модели более полезно: состояние или поведение?

Поскольку любое движение относительно, мы можем считать геоцентричную модель не менее правильной нежели гелиоцентричная. Если земля вращается вокруг оси == вселенная вращается вокруг земли. То же самое можно сказать вообще о любом объекте, хоть космическом, хоть не очень.

ну да, геоцентричная с эпициклами тоже вполне себе работает, в своих пределах: см. древнегреческую космологию, экванты, эпициклы, противоземлю, «подлунную небесную сферу»,космологию вот это всё.

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

правда, вылезли проблемы, которые пытались решать астрономы-мусульмане. получилась уже изменённая модель, отсюда — модель Тихона Браге.

там уже не «земля вокруг центра эпицикла, и вокруг солнца», и не «солнце вокруг земли», а они оба вокруг своих центров.

вообще-то, земля кружится вокруг солнца — не только в плоскости эклиптики, а +- несколько от неё, по спирали. и солнце кружится вокруг центра галактики. и этот центр — вокруг центра вселенной. и вселенные вокруг метавселенной.

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

Это и проблема логики, в том числе. Есть некое выражение, которое должно вычислится либо в истину либо в ложь. Но сами истина и ложь относительны, а классическая логика не будет работать, без допущения, что они абсолютны

корень какой-то логики — это разрешение противоречий, логических парадоксов. то есть, с точки зрения новой «металогики», новой парадигмы эти противоречия становятся гранями одного целого единства, в динамике, диалектически. потом, может быть не «или-или», а «и-и», в какой-то своей мере.

вопрос в соотношении этой меры и т.н. реальности.

и опять же: что более полезно: состояние или поведение?

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

в контексте этого треда: есть поведение, интерфейс *print-readable* или просто *printable*. есть совместимость по интерфейсам read/write, изоморфизм состояния. правда, есть некоторые символы, которые невозможно read, пока не перекроешь интерфейс. то есть, read после такого write прочитается не в тоже самое, что распечатывалось (пока интерфейс не реализован). то есть, изоморфизм состояния нарушится.

поэтому можно сказать, что состояние всё-таки тоже важно. например, рекурсивные структуры данных в лиспе, gensym символы и т.п.

то есть, такой минималистичный интерфейс как соотношение между поведением и состоянием, какая-то количественная мера этого отношения — практически полезен.

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

так что порочна эта идея (в том топике) или нет — зависит от этого самого отношения, меры полезности.

а так-то, ты конечно прав (в какой-то мѣре): MDL изначальный из лаборатории группы динамического моделирования MIT, Project MAC.

если ты почитаешь исходники изначального Zork на MDL, и далее ZIL (например, в Zilf) то там этот паттерн всю дорогу:

<OBJECT CLOAK
    (DESC "cloak")
    (SYNONYM CLOAK)
    (IN PLAYER)
    (FLAGS TAKEBIT WEARBIT WORNBIT)
    (ACTION CLOAK-R)>

<ROUTINE CLOAK-R ()
    <COND (<VERB? EXAMINE> <TELL "The cloak is unnaturally dark." CR>)>>

то есть, у каждого объекта своё поведение(рутина), и COND-ами реализована система правил, rulebook. почти как FSUBR, фекспры.

далее пути исследователей из этой лаборатории разошлись: Carl Hewitt начал строчить методички по акторам, Gerald Sussman занялся методичками со схемой и лямбда-исчислением как акторами, кто-то занялся игрушками на Interactive Fiction и ушёл в Infocom.

тот MDL изначальный был ближе к истокам.

anonymous
()

без либ haskell умеет(если правильно реализованы инстансы Read/Show; дефолтные всегда правильные), js умеет

у тех, что не умеют по дефолту, обычно есть либы для сериализации

f1u77y ★★★★
()
Ответ на: комментарий от den73
GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/f1u77y/.ghc/ghci.conf
 > data Foo = Foo { bar :: String, baz :: Foo } | Bar deriving (Read, Show, Eq)
 > let foo = Foo { bar = "bar", baz = Foo "baz" Bar }
 > show foo
"Foo {bar = \"bar\", baz = Foo {bar = \"baz\", baz = Bar}}"
 > read (show foo) == foo
True
f1u77y ★★★★
()
Ответ на: комментарий от anonymous

Gerald Sussman занялся методичками со схемой и лямбда-исчислением как акторами

Кстати, они разошлись и еще в одном: Сассман(со Стилом) утверждали, что они реализовали акторы, однако, Хьюитт так никогда не считал

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

Для полноты картины добавлю, что в хаскеле таким же автоматическим образом можно получить преобразование в JSON, туда и обратно, а также в двоичный формат, дописав или переписав некоторые куски, если необходимо. Не только и не столько текстовое представление.

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

согласен. можно через геттеры/сеттеры реализовать (императивный интерфейс) или монаду State (функциональный). то есть, полиморфный интерфейс поведенческий.

вывод: никаких особых состояний сознания нет, но есть особые поведения (этого сознания), и паттерны таких поведений.

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