freenode/lisp - IRC Chatlog
Search
21:30:39
housel
In another channel I'm in (#dylan), it is always morning by convention; makes it easier to choose a greeting across time zones
22:12:43
White_Flame
(defun make-multiplier (x y) (let ((scale (* x y))) (lambda (in) (* in scale)))
22:20:32
aeth
What I mean about not optimized is that given a sufficiently smart compiler both (defun foo () (mapcar (alexandria:curry #'* 2 3) '(1 2 3))) and (defun foo () (quote #.(mapcar (alexandria:curry #'* 2 3) '(1 2 3)))) would be compiled to constantly return '(6 12 18) but that's clearly not the case, at least in SBCL.
22:21:30
aeth
(well, actually it should return (list 6 12 18) in the former case. Slightly different in that modifying the quoted version is undefined and could have unexpected behavior)
22:21:55
oni-on-ion
i did disasm (mapcar (lambda (x) (* x 8)) '(1 2 3 4)) its only a page, that julia was about 4-5 pages....
22:23:05
aeth
I then have to quote it because it tries to evaluate (6 12 18) as a function with two arguments and the name 6
22:23:27
oni-on-ion
so ur telling me that lisp is the perfect balance and harmony between man and machine
22:24:01
aeth
oni-on-ion: No, I'm saying that even here Lisp is incorrect because given entirely constant data, a sufficiently optimizing compiler will compile it to a constant return value, without needing a hack like evaluating that at read time
22:24:48
aeth
In fact, I wouldn't be surprised if the equivalent multiplication in LOOP on the quoted list *does* return a constant
22:26:07
aeth
are you disassembling the reader version in SBCL? for me it returns '(6 12 18) in 23 bytes
22:28:10
aeth
oni-on-ion: (disassemble (lambda () (quote #.(mapcar (lambda (x) (* x 8)) '(1 2 3 4)))))
22:31:17
aeth
oni-on-ion: this won't be as concise as the reader version because I'm using LIST instead of QUOTE: (defmacro times-eight (list-of-numbers) `(list ,@(mapcar (lambda (x) (* x 8)) list-of-numbers)))
22:32:25
aeth
You can get the same thing with (defmacro times-eight* (list-of-numbers) `(quote ,(mapcar (lambda (x) (* x 8)) list-of-numbers)))
22:33:58
aeth
The *disadvantage* of the macro approach is that even though it's more general than the reader approach, it still won't always give you want you want.
22:34:47
aeth
e.g. a list of (1 2 (* 2 2) 4) will fail. If you wanted to be totally general, you'd have to walk through, see if something is a number, if it's a number apply the multiplication, and if it's not a number, make sure the multiplication is attempted at run time.
22:35:16
aeth
oni-on-ion: Putting the ` and ,@ in the lambda itself is doing the operation at run time each time the function is called, even though your data is constant
22:35:27
aeth
oni-on-ion: The ` and ,@ in the macro will do the computation once, when compiling it.
22:35:29
oni-on-ion
i think im just attacking code translation. reason i mentioned balance and harmony earlier, getting to it..
22:35:53
oni-on-ion
aeth: oh! i didnt know that. when to get macros eval'd at compile? eval-when obviously then ?
22:36:16
oni-on-ion
for some reason i didnt lose any marbles by assuming ` and @ were compile time or even just eval time.
22:37:00
aeth
oni-on-ion: this is the full version you want, btw. (defmacro times-eight (list-of-numbers) `(list ,@(mapcar (lambda (x) (if (numberp x) (* x 8) `(* ,x 8))) list-of-numbers)))
22:37:33
aeth
oni-on-ion: If it's a number at macro-expansion time (i.e. a literal number like 42) it will do the multiplication then. If it's not a number (e.g. the list (* 3 4)), then it will attempt to do the multiplication at run time
22:38:46
aeth
the macro is essentially taking in '(1 2 3 4 (* 3 4)) and returning '(list 8 16 24 32 (* (* 3 4) 8))
22:39:38
aeth
and it will even work with variables. (macroexpand-1 `(times-eight (1 2 3 4 foo))) => (LIST 8 16 24 32 (* FOO 8))
22:40:52
aeth
Now there still is a generic-* but it's only applied once, to the variable foo, instead of on every item, which are mostly constant. We turned the naive map into the most efficient thing we can do.
22:44:36
aeth
oni-on-ion: the only catch is that we're not really working on a list. (1 2 3 4 foo) is syntax. (times-eight foo) won't work because it will see the symbol foo instead of a list there, at macro-expansion time.
22:45:11
aeth
Because that's misleading we can express the macro like this: (defmacro times-eight (&rest list-of-numbers) `(list ,@(mapcar (lambda (x) (if (numberp x) (* x 8) `(* ,x 8))) list-of-numbers)))
22:46:48
aeth
Alternatively, we could attempt to parse the argument in the macro and have a slow version for when it's not what we want. Then we could have (times-eight (list 1 2 3 4)) as the API, and for everything that's not a list that begins with LIST we can provide the slow, runtime route.
22:48:57
aeth
This would be the implementation: (defmacro times-eight* (list) (if (and (listp list) (eql (car (list)) list)) `(list ,@(mapcar (lambda (x) (if (numberp x) (* x 8) `(* ,x 8))) list)) `(mapcar (lambda (x) (* x 8)) ,list)))
22:49:56
aeth
But essentially the idea is that if the list is known at compile time, handle it in an optimal way. If it's unknown, just do the mapcar like you would have done.
22:54:52
oni-on-ion
right =) i will get used to swapping between compile and run time , glad the syntax is super small for it
23:07:44
jasom
also consider that for when you might want to behave as a function or a macro depending on your arguments.
23:12:52
aeth
jasom: You can use "list" everywhere but you still might accidentally use the wrong list
23:15:31
aeth
This is the correct version: (defmacro times-eight* (list) (if (and (listp list) (eql (car list) 'list)) `(list ,@(mapcar (lambda (x) (if (numberp x) (* x 8) `(* ,x 8))) (cdr list))) `(mapcar (lambda (x) (* x 8)) ,list)))
4:47:10
oni-on-ion
LdBeth: the practical way is to have superclass-1 and superclass-2 come from superclass-0 then dispatch on that, i think.
5:14:59
aeth
LdBeth: there's always the ugly, messy, hackish solution of writing a macro to generate two methods, one for superclass-1 and one for superclass-2, with the same body.
5:21:22
aeth
With a macro-generated approach I'd be thinking of something along the lines of this: You would need to make sure that both methods got called if both were valid, and only call the "real" method if both methods got called. Probably messier than the other two approaches.
5:26:18
aeth
e.g. NIL as a member of null has two distinct parent classes (list and symbol) and you can go into both in some order via: (defmethod foobar ((foo symbol)) (format t "symbol ~S~%" foo) (when (next-method-p) (call-next-method))) (defmethod foobar ((foo list)) (format t "list ~S~%" foo) (when (next-method-p) (call-next-method)))
6:09:50
LdBeth
ACTION uploaded an image: 屏幕快照 2018-09-26 下午11.09.13.png (39KB) < https://matrix.org/_matrix/media/v1/download/matrix.org/fOFZzRGdNykCWdETdqweudZU >
7:34:56
shrdlu68
pjb: It occured to me that O(log n) ought not be 10 times slower than 0(1) when n=240
7:39:04
beach
shrdlu68: Different algorithms have different overhead, so different constant factors. Having said that, I should point out that lb(256) = 8 so 10 doesn't sound strange at all.
7:44:10
no-defun-allowed
so if using, say, O(n) lists and O(1) vectors, if vectors are 3 times slower (which is unlikely, just for an example), it's really O(n) and O(3)
7:45:56
no-defun-allowed
to rephrase that, "the relative time taken for each structure would be n and 3" i guess
8:01:49
Demosthenex
so where do you go for lispy news? reddit's /r/common_lisp? y combinator's hacker news?
8:17:16
LdBeth
ACTION uploaded an image: 屏幕快照 2018-09-27 上午1.16.43.png (400KB) < https://matrix.org/_matrix/media/v1/download/matrix.org/DJIrWfVadwmrKqPwZaxYbINN >
8:19:25
adlai
Demosthenex: no matter where i get my news, i have never encountered the journalist lispy enough to try slipping nestted parentheses by the copyeditor
8:23:32
beach
What part do you think might be a bug, and do you think it might be a bug in CCL or something else?
8:31:05
shka_
https://european-lisp-symposium.org/static/2018/heisig.pdf obviously, there ELS presentation
8:34:40
Shinmera
no-defun-allowed: what's your guess on this one? https://github.com/Shinmera/talks/blob/master/els2018-glsl-oop/presentation/static.pdf
8:37:32
no-defun-allowed
and the teacher used the google drive pdf viewer which is all blurry and horrible cause she didn't download it either she just zoomed in the browser
8:38:17
Shinmera
Or in action here https://www.youtube.com/watch?v=od6WI7JIJcQ&list=PLkDl6Irujx9PL5LfhvvkkeMiCiDij8jzM&index=5
8:38:24
no-defun-allowed
i only could tell beamer cause a. duh this is #lisp and b. i recognise the font
8:45:21
no-defun-allowed
(tldr: watched a security conference, saw neat presentation on wpa cracking with fpga, wondered why no one sells these things to skiddies and or pentesters)
8:48:57
Shinmera
I'm still looking into that. I'm meeting with some googlers this Friday to see what we want to do. I'll try contacting the ETH secretary based on what we decide there
8:51:16
francogrex
is there a reason why when I load clsql package, SBCL 1.4.2, recompile most of the already compiled file every time!? for example all files in clsql/uffi/ and clsql/db-oracle/ compiling (IN-PACKAGE #:CLSQL-UFFI)... etc. I though when nothing is changed it just loads the already compile files?
8:53:08
no-defun-allowed
schema is usually used for documents of some kind and i think that's a more appropriate word though
9:15:03
heisig
Ah, I see people demanding more documentation for Petalisp. Well, I am working on it... but I am not willing to document an API that is still under development. Give me a few more weeks.