freenode/#lisp - IRC Chatlog
Search
18:56:13
jmercouris
I'm trying to determine if a symbol points to a function, I tried typep, but a functions symbol is of course just a symbol
18:59:30
White_Flame
there's fdefinition, fboundp, and a few others, but I think they all "signal" a condition if it's not a function
19:00:42
sjl
I don't think there's a function-designator-p defined by the standard, you'll probably have to implement it yourself
19:03:23
phoe
a function designator is one of the following: a function object, a symbol, or a list (SETF FOO) where FOO is a symbol.
19:04:16
jmercouris
so, I don't have to worry about hitting any edge cases as it will only be my own code
19:04:32
White_Flame
from the spec: fboundp is sometimes used to ``guard'' an access to the function cell, as in: (if (fboundp x) (symbol-function x))
19:06:14
sjl
phoe: not sure that last one is correct. (funcall '(setf car) :foo (list 1 2 3)) fails in SBCL with:
19:11:40
sjl
I wouldn't say it's "not following the standard" because it's not claiming to be function-designator-p
19:12:03
sjl
it's doing its own thing, and that happens to be something like jmercouris probably wants
19:12:27
phoe
I mean - it accepts an argument named FUNCTION-DESIGNATOR that does not have to be a function designator despite its name.
19:13:26
phoe
It makes a logical distinction, it's either a function or a function *name*, not designator.
19:13:53
phoe
But I can perfectly see why it is like that, and I don't want to change that behaviour.
19:50:55
jackdaniel
hey, anyone having ACL around? I'd appreciate trying to compile CLX (from develop branch) on it
19:56:42
phoe
the standard says nothing if it's permitted and/or intended for programmers to explicitly call initialize-instance in client code.
19:57:18
specbot
Object Creation and Initialization: http://www.lispworks.com/reference/HyperSpec/Body/07_a.htm
19:57:39
phoe
"The generic function shared-initialize implements the parts of initialization shared by these four situations: (...) when re-initializing an instance, (...)"
20:08:43
Bike
reinitialize-instance might not "reset" an instance depending on what you mean by that, though. particularly it doesn't reinstall any initforms.
20:08:58
didi
Idle thought: Isn't it interesting that #'format uses a control /string/ instead of a control /list/?
20:10:58
Bike
~{~a ~} being (start-loop aesthetic " " end-loop) would be kind of weird. ((aesthetic " ")) or something, indicating the loop as part of the structure would make more sense
20:16:55
jmercouris
Alright, so I'm working on a way to be able to pass something like '(print "lol") to (funcall)
20:17:22
jmercouris
I have a simple approach that is basically (funcall (first list-of-things) (rest list-of-things))
20:17:58
phoe
"~:[{~;[~]~:{~S~:[->~S~;~*~]~:^ ~}~:[~; ~]~{~S->~^ ~}~:[~; ~]~[~*~;->~S~;->~*~]~:[}~;]~]"
20:20:06
jmercouris
didi: just to be completely clear about my objective- I want the user to be able to pass a function as they normally would with args like this: '(function any-number of arguments :including-keyword args) and then execute that call at a later time
20:20:47
jmercouris
didi: does that make sense? or is my explanation not so good? I am pretty tired at the time
20:21:25
phoe
I'd rather pass the function object that I control rather than an arbitrary number of forms that you need to eval at runtime.
20:22:02
phoe
and no, it's not a burden. eval-at-runtime is pretty evil in Lisp anyway, and should be avoided wherever possible.
20:23:33
phoe
either a lambda without arguments *OR* a lambda with specified arguments that you will pass to it.
20:24:07
Bike
why can you not just do (push (lambda () (setf ,variable ,value)) *deferred-variables*)
20:24:10
phoe
like, if you want to execute user code that will do some things with object FOO, then you will want to accept functions like (lambda (foo) (user-code foo))
20:24:22
Bike
(incidentally, that's a thunk right there. you already understand this concept, hooray)
20:24:42
phoe
or you can go the around route and define *foo* as a dynavar, and expect your users to grab its value that way.
20:25:11
phoe
this way, you can "work around" the issue with function arguments. you just hide them in dynamic variables, which is ugly in its own way.
20:25:14
Bike
say you have (deferredvar fishes-count (count-fishes :type "salmon")), which i believe was what you wanted your example to be
20:25:36
Bike
this will macroexpand into (push (lambda () (setf fishes-count (count-fishes :type "salmon"))) *deferred-variables*)
20:25:40
jmercouris
Yeah, it was, but I changed it for simplicity half way, missed a few spots I guess :D
20:26:35
jmercouris
I wasn't thinking straight, I was thinking of it as multiple values, but it is just a single list
20:27:23
_death
I use :default-initargs to.. pass defaults for initargs :).. if a slot has no initarg, then I use :initform
20:35:52
Bike
i found a probably longstanding if nontrivial to trigger bug in ecl about them the other day, but just due to reading source
20:48:51
didi
I shall put this `out' macro with the series package for when I am courageous enough to incorporate them into my programs.
21:06:13
jmercouris
Ah, nvm, I do see how it is possible, sorry for the interruption, I should probably just go to sleep
21:36:40
_death
jasom: if you mean the one in ytools, it doesn't.. for my own, I use an old trick to pass context around
22:21:34
Xof
in one of those Small World kind of things. "What do you do?" "Oh, really, what lisp do you use?" "Oh, really, do you want to know something funny?"
22:22:39
Xach
Lisp music software seems to exist in its own world (much like every other piece of the lisp world)
22:58:13
stylewarning
One exercise in Scheme is learning how to do macros that capture name. One such exercise is writing a macro with-degrees (&body) which lexically captures sin/cos/tan and defines them as functions of degrees. In Common Lisp, you can't lexically shadow symbols in the CL package.
22:58:43
stylewarning
Nonetheless, I'm curious how someone might actually solve this. Code walk and replace? Does anyone have a simple example of how to do it with current libraries?
23:06:21
p_l
I'd love a "trivial-codewalker" that would just hook into compiler innards of the implementation in layerable way :<
23:09:30
scymtym
p_l: https://github.com/scymtym/sbcl/blob/wip-walk-forms-new-marco-stuff/examples/code-walking-example-without-clos.lisp
23:26:57
jasom
stylewarning: just shadow the symbols in your current package, and set their fdefinition to be the CL: equivalent
23:27:46
stylewarning
jasom: of course you can do that; the idea of the exercise was to just provide a small convenience without extra packages and the like
23:28:03
stylewarning
and of course it's not possible, with a macro, to change the package over the lexical scope of the macro
23:28:54
jasom
stylewarning: short of walking the entire tree and replacing the symbols, I can't think of a way. If it were easy that would violate a core part of lisp's macro hygiene
23:29:22
stylewarning
jasom: Sometimes I do wish it were possible to selectively turn that stuff off.
23:29:42
jasom
stylewarning: sbcl lets you disable package locks, so you can on at least one specific implementation
23:34:17
stylewarning
jasom: I need to learn more about these neat features of SBCL. I usually scan the manual every so often, but I guess I missed/forgot this.
23:36:39
scymtym
stylewarning: speaking of which: we just made the manual look a little nicer and documented the different kinds of timeouts in SBCL
23:49:36
scymtym
didi: we just applied a different stylesheet to the HTML version. does that alleviate your concerns?
3:26:06
borei
i have question about lisp code optimization - matrix multiplication in my case. i undestand that topic is rather big, but still, some recommendations would be nice. I was trying to find best solution in C/C++ but didn't get explicit answer for it
3:27:23
borei
i store matrix elements in 1-dimensional array (simple-array) - that guarantee that data will be continouse
3:28:40
borei
to multiply matricies i can create nested loop with proper indexing, so it will do proper elements multiplication
3:29:29
borei
or i can pull row(s) and column(s) from input matricies and do multiplication (scalar multiplication) on them
3:30:50
borei
in second approach im hoping that vectors (rows and colums) will fit cache, but i can't control it
3:32:37
borei
in first approach more or less big matrix will not fit cache for sure, but there is no overhead on moving data, only access to elements
3:33:32
borei
there is 3rd approach - block matrix multiplication, but it's more complex in terms of the algorithm
3:36:50
pierpa
by copying parts of the arrays somewhere else you won't diminish the amount of cache needed. On the contrary.
3:41:24
borei
pierpa: i was hoping that when i extract row (or columns) from matrix it will fit CPU cache, and multiplication will be done much faster, comparing pulling out individual element from huge array
3:42:15
pierpa
the extracted column may fit the cache, but to extract the it in the first place you have to traverse the data in the matrix, no?
3:43:13
pierpa
since you are traversing the matrix just multiply the numbers rather than copying them somewhere and then multiplying them
5:29:29
beach
I am not an expert, but I know there are better ones. See for instance: https://en.wikipedia.org/wiki/Matrix_multiplication#Algorithms_for_efficient_matrix_multiplication
5:31:01
beach
borei: I think if you are going to build a library for such things, you need to read up on current best practice.
5:31:45
beach
borei: Careful though, it looks like Strassen's algorithm is based on the idea that multiplication is way more expensive than addition. That may no longer be the case.
5:32:51
beach
borei: Also, since all modern Common Lisp systems have threads, you may want to investigate parallel algorithms for use when the matrices are big.
5:34:43
beach
borei: But then again, perhaps your goal is not excellent performance. I was just guessing that since you mentioned execution time.
5:36:42
beach
It is a vast domain that many very smart people have been working on for a long time, so yes, there is a lot of reading to be done.
5:52:15
jack_rabbit
I've noticed in some .asd files that keywords are prefixed with '#'. What is the difference between e.g. :foo and #:foo?
5:57:55
jackdaniel
if you use foo in asd definition, you "pollute" asdf-user package (or whichever package you are in)
5:58:02
jack_rabbit
I see. So it's just to avoid interning the symbols, since they're only needed for loading.
5:58:51
jackdaniel
yes, especially that they are used only for their names. afair asdf coerces them to downcase strings anyway
6:13:55
beach
jack_rabbit: It is not only a matter of avoiding the "pollution" of the keyword package. It is also a message to the person reading your code, that the package of the symbol does not matter. If you use a keyword, then the person reading your code can't immediately know whether the package is important or not.
6:18:05
jack_rabbit
beach, aren't keywords package-independent? Or rather, they are all interned into the keyword package? When would the package be important when using a normal keyword?
6:20:06
jackdaniel
jack_rabbit: it may be important for instance in eq comparison (which you have mentioned)
6:20:43
jackdaniel
or take example, which is untrue for asdf: systems are represented by symbols (not strings) - in such scenario you could specialize methods via eql
6:20:56
beach
jack_rabbit: A keyword is by definition a symbol that has the KEYWORD package as its package.
6:22:16
jack_rabbit
jackdaniel, so I would use non-interned symbols when I don't care that they are eq.
6:22:35
beach
jack_rabbit: There are a number of situations where the package of a symbol is important. For example, if you do (find ... :test ...) you can't do (find ... #:test ...) and expect the same result.
6:23:26
beach
jack_rabbit: No, you would use uninterned symbols when you want the person reading your code to know that the package of the symbol doesn't matter.
6:23:32
jackdaniel
jack_rabbit: that's not exactly what I meant. If systems were represented by symbols, you wouldn't want to use uninterned symbols at all, you'd want to use interned ones instead (all the time). but this is only hyphotetical situation
6:24:42
jack_rabbit
jackdaniel, Yes, I get that. But that is due to the fact that you'd want to be able to compare the symbols and determine that they are eq or not, right?
6:25:50
jack_rabbit
beach, Sorry, maybe I'm being dense. I don't get the association with package. Can you give an example of when the package does not matter?
6:25:54
beach
jack_rabbit: EQ comparison is one possibility, but I can see situations where nobody cares about EQ, but the package is still important.
6:26:15
jackdaniel
not only that – imagine hypothetical function find-system. you don't care how it is compared, but if it is implemented to work on symbols then you wouldn't be able to look for a system denoted by a specific symbol
6:27:00
rme
people often use uninterned symbols (and keywords) as string designators. Instead of writing "FOO", they write :foo or #:foo
6:27:02
beach
jack_rabbit: One such example is in the name of the symbols exported in a DEFPACKAGE form. These names are used only as string designators.
6:28:16
jack_rabbit
beach, So with keywords, you say that the package is still important because the fact that they are all in keyword package has consequences?
6:29:08
jack_rabbit
Because to me, it seems that keywords are a way to use symbols without regard to a particular package (except implicit keyword package I guess.)
6:29:40
jack_rabbit
OK. So the only time non-interned symbols are useful is if they are used as string designators?
6:30:05
stylewarning
jack_rabbit: they are also useful when you wish to produce symbols for bindings
6:30:20
beach
jack_rabbit: I am not saying that the package IS important for ALL uses of keywords. We already had an example of that, e.g. when you use a keyword as a string designator. I am saying that the person reading your code MUST ASSUME (until proven wrong) that the package of a symbol is important, unless it is an uninterned symbol.
6:30:37
phoe
(let ((gensym '#:foo)) ...) - though this is mostly abstracted away via #'GENSYM and ALEXANDRIA:WITH-GENSYMS.
6:31:14
phoe
and what beach said - using an interned symbol implies that the package *may* be important in that context.
6:31:42
phoe
doesn't have to be, like LOOP discards package information for its loop keywords, but in general, you can't rule out the possibility.
6:32:01
beach
Exactly. So you put an additional burden on the person reading your code by being less specific than you could be.
6:32:54
phoe
jack_rabbit: because you generate the symbol once and put the same generated symbol in all the places.
6:34:11
jack_rabbit
phoe, yes. Because something is bound to the instance of the symbol, I can reference the same symbol in multiple places through the binding.
6:34:49
phoe
LET only wants symbols that already aren't constant variables so it can bind lexivars to them.
6:35:42
jack_rabbit
I just mean, I understand that the reader reads each instance of #:foo as a different symbol, but with the gensym, I'm binding a particular instance and reusing that, which is why it works, right?
6:37:40
flip214
is there some machine-readable version of ROOM? One that returns an alist or plist or so?
6:38:01
phoe
So (list #1=(make-hash-table) #1# #1# #1#) will give you a list of four elements. All of these elements will be EQ to each other, meaning they're the same object.
6:39:05
phoe
jack_rabbit: not really. The integer is used as a reference number internally in the reader.