LINUX.ORG.RU

Что-то лисперы на сатанизме повернуты. Родители в детстве библией по голове бьют, потом вот такие фрики вырастают.

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

Хочу при вызове функции определять макрос на основе лексической переменной 'x' и юзать этот макрос внутри функции.

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

Во-первых, в кложуре считается плохой идеей использовать не top-level дефайны. Во-вторых, макросы разворачиваются в компайл-тайме, когда никакой переменной 'х' еще не существует.

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

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

Во-первых, в кложуре считается плохой идеей использовать не top-level дефайны. Во-вторых, макросы разворачиваются в компайл-тайме, когда никакой переменной 'х' еще не существует.

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

Мда . . . Вы по моему все перепутали. Когда макрос разворачивается ему ни какая переменная «x» не нужна. Т.к. он не каких параметров не получает.

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

Хочу при вызове функции определять макрос на основе лексической переменной 'x' и юзать этот макрос внутри функции.

Вы по моему все перепутали. Когда макрос разворачивается ему ни какая переменная «x» не нужна. Т.к. он не каких параметров не получает.

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

korvin_ ★★★★★
()

Так в кложуре то в топлевеле всё равно объявляются. Какой смысл? Это во-первых. Во вторых, что это за макрос такой? Он же не делает какую-либо форму, а просто должен возвращать x? Тогда нужно defn вместо defmacro. Пример вместо x - `(println ,x). Вот это будет форма, которую будет делать defmacro.

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

Он просто недопонял немного, что в компайл-тайме x ещё нет.

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

Пример вместо x - `(println ,x)

'(println x)

Если же ты имел в виду

`(println ~x)

то это тоже не будет работать по тем же причинам.

В его случае достаточно 'x.

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

Имел в виду ~x и оно будет работать, но сейчас узнал, что в кложуре и ,x канает. В смысле, да, сам макрос не будет работать, это я форму привёл, но в квазицитировании в кложуре можно и , использовать.

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

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

Нет он сказал что

макросы разворачиваются в компайл-тайме, когда никакой переменной 'х' еще не существует.

А в реальности переменная x существует и в «рантайме» и в «компиле-тайме»

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

А в реальности переменная x существует и в «рантайме» и в «компиле-тайме»

Не существует она в компайл-тайме, т.к. создается в рантайме.

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

Не существует она в компайл-тайме, т.к. создается в рантайме.

То есть в моем примере, в «компайл-тайме» переменной «x» не сущетсвует. ?
И к чему это приводит? К тому что макрос не определяется или не раскрывается?

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

Хочу при вызове функции определять макрос

У тебя какаша в гойлове.

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

Что-то сглючило что ли меня. :) Отчётливо помню, что запятуха процитировалась. :) А сейчас пробую ещё раз - нет.

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

Ну попробовал и, вроде, получилось. Может, конечно, окно перепутал. :)

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

Я специально выложил простейший пример который выдает ошибку. Что-бы обсудить именно область видимости defmacro. А не возможности реализации того или иного функционала. Изначально функция должна была получать выражение clojure в виде строки и выполнять ее. Но вот беда, eval ни как ни хочет видеть локальные переменные. И я решил поэкспериментировать с defmacro.

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

Но вот беда, eval ни как ни хочет видеть локальные переменные.

Локальные переменные существуют только в коде. Во время исполнения программы их _нет_

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

Локальные переменные существуют только в коде. Во время исполнения программы их _нет_

Этот пример доказывает обратное.

(let [x 2]
 (println "local X = " x))

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

Изначально функция должна была получать выражение clojure в виде строки и выполнять ее. Но вот беда, eval ни как ни хочет видеть локальные переменные.

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

Тебе нужно это (взято из M.Fogus «The Joy of Clojure»):

(defmacro local-context []
  (let [symbols (keys &env)]
    (zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols)))

(local-context)
;=> {}

(let [a 1, b 2, c 3]
  (let [b 200]
    (local-context)))
;=> {a 1, b 200, c 3}

(defn contextual-eval [ctx expr]
(eval
`(let [~@(mapcat (fn [[k v]] [k `'~v]) ctx)]
~expr)))
unlog1c ★★★
()
Последнее исправление: unlog1c (всего исправлений: 1)

defmacro как define-syntax, только для топлевела. Аналога let-syntax в Clojure нет.

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

У тебя запутанный пример. По докам defmacro то же, что и defn, но для макро, а defn это то же, что и def, но для функций, а def это объявление в топлевеле. А «выражение clojure в виде строки» мне это до конца не понятно. Парсить что ли?

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

Благодарю за код и за книгу . Это то, что надо.

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

Если я тебя правильно понял, то тебе нужно было что-то типа:

(defmacro bu-gaga []
  'x)

(defn mu-haha [x]
  (bu-gaga))

(mu-haha 555) => 555
turtle_bazon ★★★★★
()
Ответ на: комментарий от turtle_bazon

А какая от этого предполагаемая практическая ценность?

А какая разница? Человек четко (в итоге) поставил задачу, задача известная и имеет решение, зачем еще передергивать. Надо значит надо.

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

Надо значит надо.

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

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

При выполнении этого кода никаких локальных переменных нет. Компилятор просто заинлайнит х и получится (println «local X = » 2)

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

При выполнении этого кода никаких локальных переменных нет. Компилятор просто заинлайнит

Ну фигню же несешь. Зачем человека с толку сбиваешь?

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

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

Общался. Если задача выполнима — делаю, если нет — выясняя зачем это надо.

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

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

А вот и еще один виртуал terminator-101.

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

У тебя каша в голове. Ты не понимаешь ни области видимости, ни макросов.

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

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

Казалось бы, при чем тут макросы и eval строки?

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

Прочитай и просветлись: http://nicholaskariniemi.github.io/2014/01/26/clojure-compilation.html

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

(let [x (do (println "will be printed once") 42)]
  (+ x x x x x))
; will be printed once
;=> 210
unlog1c ★★★
()
Ответ на: комментарий от anonymous

Убогий упорышь, у тебя от слов constant folding икота, да?

Кококо? Первое что ты сказал было inlining, теперь сьезжаешь, зашкваренок?

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

Ну давай, похвастайся своим компилятор Clojure, я заценю.

unlog1c ★★★
()
Ответ на: комментарий от anonymous
(let [x (str "foo" "bar")]
  (str "baz" x))
// const0 = clojure.core/str

0: getstatic     #23                 // Field const__0:Lclojure/lang/Var;
3: invokevirtual #31                 // Method clojure/lang/Var.getRawRoot:()Ljava/lang/Object;
6: checkcast     #33                 // class clojure/lang/IFn
9: ldc           #35                 // String foo
11: ldc           #37                // String bar
13: invokeinterface #40,  3          // InterfaceMethod clojure/lang/IFn.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
18: astore_1                         // Эта JVM-операция означает "анонимус обосрался"
19: getstatic     #23                // Field const__0:Lclojure/lang/Var;
22: invokevirtual #31                // Method clojure/lang/Var.getRawRoot:()Ljava/lang/Object;
25: checkcast     #33                // class clojure/lang/IFn
28: ldc           #42                // String baz
30: aload_1       
31: aconst_null   
32: astore_1      
33: invokeinterface #40,  3          // InterfaceMethod clojure/lang/IFn.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
38: areturn
unlog1c ★★★
()
Ответ на: комментарий от korvin_

Мне в первую очередь интересно в чем у меня ошибка в коде.

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