freenode/#lisp - IRC Chatlog
Search
18:17:28
anamorphic
When I create a defun with keyword arguments, e.g. (defun foo (&key bar baz) ...), can I expect to find the keys ("BAR" and "BAZ") interned into the keywords package afterwards? Or, does that happen the first time I call the function (i.e the first time I call (foo :bar 231)
18:27:38
anamorphic
I was playing with symbol property lists, and the possibility of using them to attach metadata to keyword args. e.g. if I have some a keyword arg, :foo-callback, I was experiementing attaching metadata about the shape of the callback's argument list
18:44:28
shka_
also, symbol can name more then just a function, therefore possibility of collision exists
19:05:40
pjb
shka_: (setf car) may happen to be a function in your implementation, but it is not necessarily the case in Common Lisp.
19:06:45
pjb
It's not because you can write (setf (car k) a) that you can write (let ((vk k) (va a)) (funcall (fdefininition '(setf car)) va vk)).
19:07:07
makomo
anamorphic: hmm, interesting question. keyword symbols are by definition symbols interned within the KEYWORD package. this happens either when the code is read (if your keyword symbols appears within the source) or when you call INTERN.
19:10:03
anamorphic
I tried (defun foo (&key bar baz quux) (values bar baz quux)) and then (find-symbol "QUUX" (find-package "KEYWORD")) and it does seem to create the keywords before I using the function
19:11:34
anamorphic
Curious though, symbols can be internal or external to a package: in the case of the keyword package is there any point to an *internal* keyword?
19:12:55
pjb
makomo: when you unintern a symbol, it doesn't lose its identity. It is still referenced everywhere it's referenced (but its home package).
19:12:59
specbot
Interning a Symbol in the KEYWORD Package: http://www.lispworks.com/reference/HyperSpec/Body/11_abca.htm
19:13:17
jasom
anamorphic: interning a symbol in the keyword package automatically makes it external, per the above referene
19:13:32
pjb
Also, &key doesn't take keywords, but symbols in general. An uninterned symbol is good for a &key keyword.
19:13:39
makomo
pjb: yeah, i understand. but the question is whether one can rely on it being interned in the KEYOWRD package
19:14:12
makomo
pjb: yes, i'm also aware of that, i mentioned it above, so it doesn't directly address his/hers concern
19:16:32
jasom
anamorphic: I would guess that merely defining a function with the lambda list (foo &key bar) will not intern anything in the keyword package, but I don't know that it's defined one way or the other.
19:17:20
jasom
actually I can think of cases where it would; in order to optimize the function, it might need a reference to the keyword, which would require interning.
19:18:50
makomo
(progn (defun test (&key hello) :hello) (unintern :hello "KEYWORD") (test :hello 'there))
19:19:33
makomo
i.e. :hello wasn't interned within the KEYWORD package at the time when TEST was called
19:23:50
jasom
(defun test (&key hello) (declare (optimize (speed 3))) :hello) (unintern :hello "KEYWORD") (test :hello 'there) ;; <-- this is the test
19:23:51
pfdietz
Having it all put together in the PROGN is important, as all that gets read before the unintern occurs.
19:24:47
makomo
pfdietz: if we were to drop the PROGN, wouldn't :hello get interned again once the last form was read?
19:24:50
pjb
jasom: the trick is the progn: since it's a single sexp, all the occurences of ":hello" internalize as the same keyword!
19:25:09
pjb
(progn (defun test (&key hello) (list :hello (symbol-package :hello))) (unintern :hello "KEYWORD") (test :hello 'there)) #| --> (#:hello nil) |#
19:25:20
pfdietz
Yes, and the keyword in TEST would be the uninterned previous version, and they would not match.
19:25:28
pjb
(defun test (&key hello) (list :hello (symbol-package :hello))) (unintern :hello "KEYWORD") (test :hello 'there) #| ERROR: Incorrect keyword arguments in (:hello there) . |#
19:25:29
makomo
but i'm curious as to why it fails without the PROGN. won't the third form intern :hello again?
19:26:56
pjb
makomo: because after the unintern, the test definition is: (defun test (&key ((#:hello hello))) (list #:hello (symbol-package :hello))) #| --> test |# (test :hello 'foo) #| ERROR: Incorrect keyword arguments in (:hello foo) . |#
19:27:13
jasom
ah, this is well defined; keyword parameters are not required to be keywords, they can be any symbol
19:28:23
pjb
(defparameter *old-hello* :hello) (defun test (&key hello) (list :hello (symbol-package :hello) hello)) (list (ignore-errors (test :hello 42)) (test *old-hello* 42)) #| --> ((:hello #1=#<Package "KEYWORD"> 42) (:hello #1# 42)) |#
19:29:12
specbot
Specifiers for keyword parameters: http://www.lispworks.com/reference/HyperSpec/Body/03_dad.htm
19:29:53
jasom
so yes, defining a function with a keyword parameter must intern the symbol into the keyword package, as it needs to resolve it to a symbol. It's at least strongly implied by the spec, so I was wrong.
19:30:06
makomo
i thought about that, but thought that "foo" automatically gets interpreted as ":foo" or something. neat!
19:31:40
makomo
jasom: so by the time the function is called, you have the guarantee that the symbol is interned. what about CLOS methods though? :-) what about a :before method uninterning a keyword symbol for the primary method?
19:33:24
pfdietz
I wonder how many lisps parse ::x as :x. Undefined in the standard what happens there.
19:34:11
pjb
I get twice ((:hello :external) :hello (:hello #1=#<Package "KEYWORD"> 42) (:hello #1# 42)) I expected ((nil nil) #:hello (#:hello nil 42) (:hello #<Package "KEYWORD"> 42)) after unintern…
19:35:23
makomo
"so by the time the function is called, you have the guarantee that the symbol is interned", scratch that, obviously not true
20:03:22
jasom
actually you don't even have that; a macro could create a function with a gensym as an argument (it requires a macro because the key name is not evaluated in the lambda list)
20:04:51
jasom
(defvar *foo* (gensym)) (eval `(defun test (&key ((,*foo* foo))) foo)) (test *foo* 1) ;<-- example
20:19:28
jcowan
you definitely can unintern a keyword from the keyword package, and then it becomes a regular homeless symbol; if you recreate the keyword it is not eq to the uninterned keyword
20:19:43
jcowan
also, you can import a keyword into a package, which never occurred to me to try before
20:42:45
sjl
k doesn't get set to nil. Initiall (keywordp k) returns t, because it's a keyword. But after you unintern it from the keyword package it's no longer a keyword, because the definition of being a keyword is that it's interned in the keyword package
20:46:00
sjl
There's no real reason to unintern a keyword -- may as well just do (make-symbol "FOO") and you'll end up with an uninterned symbol with less screwing around
20:46:53
pfdietz
The issue with using "FOO" is you're assuming the lisp has readtable-case of :upcase
20:48:31
sjl
Also: there's no such thing as an "uninterned keyword". Once a symbol has been uninterned from the keyword package, it's by definition no longer a keyword.
20:48:32
rme
yeah, these days you don't really have to worry about saving symbols in order to fit on a floppy.
20:48:36
aeth
I'm kind of surprised this remained. Usually Lisp libraries are happy to be inefficient :-p
20:51:29
anamorphic
So what is the general community preference around defpackage with string vs. keyword vs. uninterned keyword reader macro thing
20:52:23
sjl
Same. It's fairly evenly split, and in practice just doesn't really matter much any more.
20:53:08
pfdietz
We can argue about much more important and currently relevant things, like vi vs. emacs or Lisp-1 vs. Lisp-N.
21:01:42
aeth
Oh, another good one: ask a question about using a library via the CFFI instead of just using pure Lisp.
21:07:16
sjl
Once you get used to naming your parameters with actual words, you'll weep when you have to go back to a language that makes you mangle them.
21:07:28
pfdietz
You don't have to worry about collisions between particular namespaces that are used separately anyway.
21:08:04
ecraven
pfdietz: the main problem I have with lisp-2 is that they are *not* in fact entirely distinct (see funcall)
21:08:35
pfdietz
Ah, funcall (and function) are explicit mappings between those namespaces, when you want to use one in positions that defaults to the other.
21:10:51
ecraven
anyway, that's the point I was trying to make. sometimes it is useful that + can be both a value and a function (in lisp-1). but sometimes, it's nice that you can name a parameter 'list' and *still* use the function 'list'
21:12:08
pfdietz
CL could be properly criticized for not separating lexical and special variable namespaces. The ears convention is a way of doing that socially.
21:12:33
xkapastel
i want *less* variable naming, not more and fancier names that even conflict with other things
21:13:12
ecraven
xkapastel: I've tried that, but keeping the stack layout in my mind isn't as easy as I had hoped :-/
21:13:31
xkapastel
if i thought my variables were gonna conflict with stuff i would write some combinators so there are just no variables at all
21:16:00
sjl
I have enough trouble remembering the correct order of gethash's arguments even with the (gethash key hash-table &optional default) arglist window staring me in the face. Not having names for parameters would be too much for my stupid brain.
21:17:14
sjl
I have no idea why gethash's parameter order consistantly trips me up more than any other function's.
21:46:18
cgay
it's backwards compared to elt and aref. (elt sequence index) (aref array subscripts) (gethash key table)
22:14:43
aeth
I think I know why it's backwards. Symbol plists! (get 'foo 'bar) gets the 'bar associated with the symbol 'foo. (gethash 'foo bar) gets the 'foo associated with the hash-table bar. GET is properly ordered (assuming that you want to match the order of aref, which has to be in the order it is). GETHASH is not.
22:16:16
aeth
But apparently, at least according to someone in #scheme who was looking into it, archaic Lisp used GET like a hash table, so (get 'foo 'bar) was used as if it was (get 'key 'table) because there probably wouldn't be too many "tables" for any given key.
22:17:23
aeth
If this is right, then (get 'turtle 'animals) could be refactored into (gethash 'turtle *animals*) fairly easily.
22:22:07
aeth
And it was probably (get 'turtle 'animals) as an optimization. Turtle would probably only have (ANIMALS #<TURTLE-OBJECT>) as its symbol plist but if it was the other way around as (get 'animals 'turtle) then you might have to walk through 100 animals on a computer weaker than today's Raspberry Pi.
22:24:04
aeth
So, basically, I now think that GETHASH is in the wrong order because people intentionally used GET in the wrong order so they could get to their turtle faster.
23:21:25
ealfonso
if I lost a reference to a usocket-server created via (usocket:socket-listen host port), is there a way to forcefully shut it down so I can start listening again on the same port?
23:35:09
ealfonso
was trying to look at the source with slime-describe-function but all I get is: Source file: SYS:SRC;PCL;DLISP3.LISP... White_Flame in that case I will probably just try to keep a reference to it in a global var
1:33:22
jcowan
Zipf's Law (or one of them) tells us that high-frequency words tend to be short, so in a planned language like a programming language you should (all else being equal) assign short names to commonly used functions.
3:30:55
no-defun-allowed
let, defun, defvar, equal, and others are good and short without being incomprehensible
4:19:48
White_Flame
of course, there's also the legacy of short names to save precious memory back in the bad old days