Fork me on GitHub
#clojure-russia
<
2016-06-10
>
andmed04:06:51

композиция функций -- крутая вещь!

andmed04:06:29

хм... (or true false) дает true. оборачиваю в функцию

(defn f [& args] (or args))
и
user=> (f true false)
(true false)

fxposter04:06:49

(apply or args)

fxposter04:06:53

ты неправильно вызываешь

andmed04:06:18

а. это потому что макрос?

Maxim04:06:26

(or '(true false))

Maxim04:06:45

так как [& args]

fxposter04:06:13

макросы тут не причем )

andmed04:06:57

неа

(defn f [& args] (apply or args))
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(/tmp/form-init296406051967001671.clj:1:18) 

andmed04:06:14

о. заработало (defn f [& args] (apply 'or args))

andmed04:06:41

вот поди-ж догодайся. "кложа бьет в поддых"

andmed04:06:22

ой, нет. оно не те ответы дает..

andmed04:06:11

кстати (or '(true false)) тоже дает (true false)

andmed04:06:27

чяднт?

fxposter04:06:27

Can't take value of a macro - а вот это потому что or - макрос

fxposter04:06:45

а то что (apply 'or args) работает - простая случайность 🙂

andmed04:06:05

не, не работает он на ней false дает, должен true

fxposter04:06:11

(or '(true false)) - так и должно давать (true false)

fxposter04:06:23

ну значит правильно - не случайность 🙂

fxposter04:06:38

нельзя макрос использовать не в первой позиции 🙂

andmed04:06:12

эмм... нормалек вообще. язык без булевых операций.

andmed04:06:21

начинаю проникаться.

fxposter04:06:49

(or (do-something-and-return-true) (do-something-and-return-false))

fxposter04:06:56

как ты это без макросов сделаешь-то?

andmed04:06:27

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

andmed04:06:38

уже нашел, можно другими функциями сделать, но все же

fxposter04:06:39

потому что макрос

fxposter04:06:06

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

andmed04:06:16

и фейлится оно неочевидно. "вот кложа вся такая"

fxposter04:06:26

(or (do-something-and-return-true) (do-something-and-return-false))

fxposter04:06:39

вот представь, как бы ты это делал на уровне функций

andmed04:06:47

угу.. но зато вот это Write a function which takes a variable number of booleans. Your function should return true if some of the parameters are true, but not all of the parameters are true. Otherwise your function should return false. вроде простой математической функцией

(and
    (not (and args))
    (or args))
тада и не сделать

fxposter04:06:08

variable number of booleans

fxposter04:06:24

any?/every?

andmed04:06:57

ага. уже нагуглил кложевей.

andmed05:06:10

кстати читал вопросы "а почему бы не ввести еще и функциональные or и and"?

andmed05:06:06

кстати в макросе or есть и vararg. а как тогда применить если apply не работает? или вызов or с параметрами вообще в функции не возможен?

nicola05:06:54

or как функция ;) - тебе к Haskell

nicola05:06:18

Нужно ленивое вычисление, чтобы управляющие конструкции писать как функции - (or (find db :andmed) (insert db :andmed))

nicola05:06:59

Если тебе нужен просто булевый or (defn bor [x y] (or x y)) и композируй сколько хочешь. Но кстати это хороший пример почему макросы хуже функций - их в рантайме просто не существует и композиция с ними не работает (точнее только в измерении макросов).

artemyarulin05:06:53

ну и напоминаю что как-раз из-за этого ограничения с макросами есть кучка хелперов any?,some,some?,every? etc

andmed05:06:22

@nicola: (defn bor [x y] (or x y)) ок. но то же с & args не работает. это потому что макросы с varargs "раскрываются" в коде иначе?

andmed06:06:15

в or макросе и два аргумента охватываются & args не пойму, почему тогда разница

andmed06:06:41

([x & next]
      `(let [or# ~x]
         (if or# or# (or [email protected]))))

andmed06:06:01

вот заработало

(defn bor [x & args] (or x args))
=> #'solutions/bor
(bor true false)
=> true

andmed06:06:20

ведь магия-же. неочевидно. или надо очень хорошо знать...

andmed06:06:30

блин (bor false false true) => (false true)

andmed06:06:32

переиначивание or и and на написание управленческих конструкций...

artemyarulin06:06:30

Ты имплементишь some как я понимаю?

artemyarulin06:06:50

а тьфу, неа, сорри

andmed06:06:08

не. Write a function which takes a variable number of booleans. Your function should return true if some of the parameters are true, but not all of the parameters are true. Otherwise your function should return false. я понял что булевые операции для этого в кложе не подходят, не вопрос, это я теперь в них разбираюсь. вот c varargs почему так...

seryh06:06:34

or принципиально нужно юзать?

(defn bor [& args] (some identity args))

artemyarulin06:06:42

в обещм посмотри сорсы того же some

(defn some
  "Returns the first logical true value of (pred x) for any x in coll,
  else nil.  One common idiom is to use a set as pred, for example
  this will return :fred if :fred is in the sequence, otherwise nil:
  (some #{:fred} coll)"
  {:added "1.0"
   :static true}
  [pred coll]
    (when (seq coll)
      (or (pred (first coll)) (recur pred (next coll)))))

artemyarulin06:06:51

через рекурсию можно сделать и без стандартных функций (я думаю смысл задачи как раз в том чтоб разобраться наверно)

andmed06:06:11

да.. это точно... про смысл LOL

artemyarulin06:06:57

через это все проходили ага - or and макросы, что за ужас, неудобно, вот счас сделаю правильно функцией - ой, не выходит, ах понятно почему так что да - хорошая задача, важная. Это из 4clojure?

andmed06:06:03

ага. "вы все еще используете or и and для булевых операций? тогда мы идем к вам"

artemyarulin06:06:00

перефразирую - "вы все еще применяете or и and не зная что это макросы - you gonna have a bad time" 🙂

andmed06:06:52

ну ок. а чо поподробнее почитать про разцицу поведения с varargs в макросах?

andmed06:06:14

или это надо в общем их освоить, скажем так...

artemyarulin06:06:18

ну и как советовали - посмотреть хаскель, единственный(?) ленивый язык в котором or and и прочее как функции возможны да

nicola06:06:44

Рекурсия - если это упражнение!

artemyarulin06:06:29

@nicola: Ты же шаришь - хаскель это вроде единственный ленивый язык где or и and возможны как функции? Или гдет еще есть?

andmed06:06:59

да, @nicola уже советовал

nicola06:06:27

Хз, мож Scala умеет ;)

artemyarulin06:06:38

ну та то все умеет ага

nicola06:06:29

Но из условно практичных, так умеют только хаскельной и смолтолк

artemyarulin06:06:23

оу, смаллталк ленивый? вау, надо почитать

andmed06:06:07

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

andmed06:06:01

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

artemyarulin06:06:33

ну дак в кложуре что есть - функции - с ними не сделать - максросы - так и сделано, "но есть нюанс” - readers - это как раз уже сам язык обрабатывает, т.е. скобочки парсятся и прочее. Делать custom reader для or/and, ну хз - не вижу смысла же

artemyarulin06:06:40

надо просто понять что такое макрос, это даже не про or|and, а вообще почему это не будет работать и про разницу macro time | runtime

(def saved-macro (if environment custom-macro1 custom-macro2))
(defn f [a]
   (saved-macro a))

prepor08:06:00

@artemyarulin: в скале можно выразить достаточно локанично or и and в качестве функций

prepor08:06:19

как и в любом языке, где есть функции высшего порядка

prepor08:06:30

в лямбда исчислении, например

prepor08:06:48

просто это синтаксически не очень будет

prepor08:06:40

вся боль на две страницы @andmed тут совершенно не понятна, в кложе прекрасно и просто сделано

artemyarulin11:06:32

@prepor: Дак так и нет. OR\And в виде функции зарезолвит все аргументы перед выполнением, чтоб сделать полноценный ор нужно либо: - оператор в языке как везде - макрос как в кложуре - ленивость как в хаскеле

prepor11:06:31

да так и да.

(defn or [x y] (if (x) true (if (y) true false)))
(when (or #(first-test) #(second-test))
  ...
`

artemyarulin11:06:32

ок, почему ор это макрос в кложуре?

artemyarulin11:06:42

а неа, сори - перечитал что ты написал, через лямбды это читинг)

artemyarulin11:06:32

да и через лямбды это по сути как раз та самая ленивость для бедных)

prepor11:06:12

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

artemyarulin11:06:39

ну ок, соглашусь

prepor11:06:07

а в скале. например, это можно сделать с call-by-name-параметрами

mike_ananev14:06:50

привет всем! кто-нибудь пробовал запускать clojure проекты под этой штукой? http://www.oracle.com/technetwork/oracle-labs/program-languages/java/index.html

mike_ananev14:06:03

вообще этим граалем кто-нибудь пользовался?

fxposter15:06:49

@prepor: я не думаю, что даже в скале call-by-name можно инлайнить таким образом 🙂

prepor15:06:02

не понимаю, что ты имеешь ввиду под "инлайнить" тут. в скале можно сделать or / and через функции именно с call-by-name

fl00r15:06:15

Андрей, не отвлекайся

fxposter15:06:26

я к тому, что по производительности достаточно непросто “заинлайнить” лямбды в or-е, чтобы он был таким же как и макрос

nicola15:06:13

@mike1452: я только где-то слышал про этот проект, но не в контексте clojure

fxposter16:06:14

нужно escape analysis делать, который даже jvm во всех случаях делать не умеет (или не хочет)

prepor16:06:41

не, ну тут вопрос что можно делать и что делается. я не знаю что сделает в данном случае скала-компилятор, но я не вижу причин, почему он не может заинлайнить как надо в принципе. в том же окамле лямбды в 4.0.3 в такой or / and функциях по идее должны заинлайниться правильно всегда.

dragoncube19:06:02

Lukas Stadler, Thomas Würthinger, Hanspeter Mössenböck: Partial Escape Analysis and Scalar Replacement for Java Proceedings of Annual IEEE/ACM International Symposium on Code Generation and Optimization (CGO'14), February 15-19, 2014, Orlando, Florida, USA

dragoncube19:06:33

вот это у них упоминается в Publications