freenode/#lisp - IRC Chatlog
Search
8:56:41
h4ck3r9696
is it possible to implement common lisp like exception handling with scheme continuations?
8:58:00
beach
h4ck3r9696: Read phoe's book. All you need is a construct for non-local control transfer, and perhaps special variables.
8:58:52
beach
I am pretty sure first-class continuations could be used for non-local control transfer.
8:59:50
beach
h4ck3r9696: And I really like the terminology that phoe created, i.e., calling it "exceptions" only when they are dumb like in most languages, and "conditions" when they are like those in Common Lisp.
9:10:25
ChoHag
h4ck3r9696: Bear in mind that scheme's continuations are undelimited and drag along the whole computation.
9:11:14
Nilby
In scheme terms, you need catch, throw, and dynmaic-wind. You could use continuations if you assume infinite stack or every function is pure and tail recursive.
9:20:30
Nilby
"This SRFI cannot be fully implemented in R5RS because it requires special support from the system,"
9:21:45
h4ck3r9696
i can tweak the interpreter, so i don't think it will be problematic to implement
9:22:44
Nilby
but it also says: "defines an exception system whose essence can be implemented with CALL-WITH-CURRENT-CONTINUATION"
9:27:41
h4ck3r9696
beach: the less memory used by the language, the more can be used for other things
9:29:52
phoe
h4ck3r9696: the less time you spend writing your own code, the more can be used for other things too
9:30:48
beach
I think it's fine to write an implementation of something like Scheme in order to learn about compiler design.
9:32:36
beach
h4ck3r9696: It would be way more efficient to write a C or assembly routine for a major Common Lisp implementation, than to resort to C for the entire thing.
9:33:04
beach
h4ck3r9696: That is why I said that your "learning" reason is fine, but the others are way less convincing.
9:34:27
beach
h4ck3r9696: I say, don't let anyone tell you what you can and can not do. But also, don't fool yourself with bogus arguments.
9:35:22
beach
h4ck3r9696: I mean, it takes way less time to learn Common Lisp than to implement a scheme compiler for the purpose of scripting a C application.
9:36:00
beach
Fun and learning are good arguments. Not knowing Common Lisp right now is less convincing.
9:40:11
madrik
Should I #' lambda forms or not? Different sources tell me different things. Is it only esthetics?
9:42:03
pjb
I agree, normally you should not use #' with lambda. However depends on whether #' is the standard reader macro, of if you changed the read table.
9:42:15
madrik
The only argument I've heard for #' before lambda is that it expressly indicates the function-ness of the form.
9:42:59
pjb
(and then, even cl:lambda may depend on whether it's the standard read-table, or a read-table that has been changed to read in another package).
9:45:39
pjb
another example is ibcl: http://informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/ibcl/index.html
9:46:23
pjb
IBCL could use the readtable trick so that cl:lambda for user code is not the Common Lisp LAMBDA… But instead it only tricked on in-package.
9:47:57
pjb
So if you write cl:defpackage you don't get ibcl:defpackage, but if you write defpackage, you get ibcl:defpackage.
9:48:31
pjb
It's important to keep in a corner of your mind the assumption with which you're working. Sometimes they're wrong.
9:49:56
pjb
For example people aways forget that entropy can only increase, but only in CLOSED systems. 1- we assume the whole universe is a closed system. 2- all the system with which we work ARE NOT closed systems!
9:51:33
pjb
madrik: the reason why I may refrain using them on internal functions is because check-type invokes the interactive debugger to resolve problems. You may want to avoid that on inner functions. But you would definitely want that for API functions and in general, functions closer to the user.
9:54:51
madrik
E.g., I learned about DEFTYPE, and thought it was possible to go overboard defining such types as positive-integer, nonnegative-real-number, etc.
9:55:29
pjb
For example (check-type i fixnum) (locally (declare (type fixnum i) (the fixnum (truncate i 2))))
9:56:35
pjb
The post assertion of check-type is that the place holds an object of that type, therefore you can tell the compiler that the object is of that type. (some compilers are dumb).
9:58:15
pjb
pyc: now, with format you can use ~& or ~%: (format nil "hello~%world") but this is not a string literal.
9:58:34
pyc
pjb: Oh, I want something like (let search-string "hello\n" ...) so that I can later do (search search-string my-string).
9:58:48
no-defun-allowed
I used funny-looking type specifiers for integers to let type inference avoid bounds checks on multiplication and all.
9:59:09
pjb
pyc: but actually we have the other, with ~newline: we can have newline in literal format control strings, and use ~newline to specify how this literal newline ust be interpreted:
10:00:39
pjb
Note that with ~newline, the prefix spaces on the following lines are ignored too. This let you indent nicely long string literals.
10:02:20
pjb
pyc: Using (format nil "hello~%") or #.(format nil "hello~%") wouldn't be too surprising. (let ((search-string (format nil "hello~%"))) (search search-string text)).
10:03:14
pjb
pyc: but you may also consider using cl-ppcre (cl-ppcre:scan (format nil "hello~%") (format nil "bonjour~% how do you hello~% world!")) #| --> 20 ; 26 ; #() ; #() |#
10:05:45
pjb
pyc: sorry, I meant: (cl-ppcre:scan "hello\\n" (format nil "bonjour~% how do you hello~% world!")) #| --> 20 ; 26 ; #() ; #() |#
10:06:23
pjb
pyc: cl-ppcre regexps are perl regexps, there "\\n" is interpreted as you want. (but it's not a newline character there, just a backslash and a n that is parsed by cl-ppcre.
10:06:50
pjb
pyc: finally, if you really need it (ie. you have a lot of strings with such escapes, you can of course define your own reader macro for #\"
10:14:35
pjb
So: (com.informatimago.common-lisp.c-string:enable-c-string-reader-macro) (write-string "hello\n\tworld!\n")
10:15:38
pjb
and: (com.informatimago.common-lisp.c-string:write-c-string "hello\n\tworld!\n") #| "hello\n\tworld!\n" --> nil |#
10:16:30
pjb
Well: (com.informatimago.common-lisp.c-string:write-c-string (format nil "hello~%~Cworld!~%~C" #\tab #\bel)) #| "hello\n\tworld!\n\a" --> nil |#
10:43:02
mfiano
Yes, don't use #'(lambda ...). There is at least one place where a lambda expression is mandated by the standard, not a function, and it's more verbose anyway.
13:01:29
pyc
In Common Lisp, the format specifier ~a is same as ~A, right? Similarly #\space is same as #\Space, right? is there any popular coding convention about which form to choose?
13:05:04
no-defun-allowed
I thought Norvig and Pitman said ~A sticks out more, but it could be anyone else.
13:06:24
pyc
no-defun-allowed: thanks for the Norvig and Pitman reference. Found https://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf Invaluable resource for a Lisp beginner like me!
13:29:24
beach
Because then you clearly indicate to the reader of your code that the package of the symbol you give is not important. Only the name.
13:30:29
p_l
CL-ASHOK: : is similarly defined as reader macro that will read the symbol as one with no value and PACKAGE set to "KEYWORD" - so every time you use :, you'll always get the same symbol from the same package
13:31:15
p_l
CL-ASHOK: #: is actually a separate reader macro, which creates uninterned symbol, so it's not a keyword
13:31:49
beach
CL-ASHOK: The @ convention is not used on IRC. Just type the nick of the person followed by : and use completion for that.
13:31:50
CL-ASHOK
so : creates keyword (which can be accessed in code), while #: implies its not going to be used anywhere else
13:32:44
beach
CL-ASHOK: It can be used elsewhere, but it means that it has no home package, so you clearly say that the package is not important.
13:32:48
p_l
#: will create a new "symbol object" every time you use it, but it won't attach it to any package
13:33:49
p_l
This is useful in various situations, for example you might want to use a symbol only for it's name value one time (used to be somewhat common in package definitions) to avoid polluting the namespace with it
13:34:40
beach
I consider the "pollution" argument as being a bit weaker. The argument that it is the most specific construct is better.
13:37:25
pyc
anyone knows what the name of the book "Let Over Lambda" means? is it a pun? if so I am not getting it.
13:38:46
beach
Also referring to the fact that LET can be seen as a special case of a compound form with a lambda expression in its CAR.
13:40:15
beach
One might think that (let ((<some-var> <some-form>)) ... <some-var>) would be the same as ((lambda (<some-var>) ... <some-var>) <some-form>) would always be equivalent.
13:42:49
beach
But they aren't when <some-var> is a lambda-list keyword. Try translating (let ((&rest 10)) (+ x 20)) to the other form.
13:42:50
CL-ASHOK
beach: "... it means that it has no home package..." --> If I use ":" then it will intern in the keyword package? Wouldn't that mean its a good thing, since a package name is like a keyword and it would not be good to have any clashes with other keywords with the same name (which may happen if its uninterned)?
13:43:37
beach
CL-ASHOK: Uninterned symbols never clash, because a new symbol is created every time.
14:04:56
nij
I guess what CL-ASHOK is concerned with is that a package should correspond to a keyword.
14:05:19
nij
But if you use #:.. it creates a different keyword everytime that corresponds to the same package.
14:17:21
gendl__
beach: nij is saying it generates a separate symbol object but with the same symbol-name, so it refers to the same package object if used with e.g. defpackage or in-package.
14:18:33
beach
I am notorious for having difficulties understanding what people say/write, unless it is very precise.
14:18:48
gendl__
he’s talking about using e.g. #:my-package in one place in code, then #:my-package again in another place.
14:19:52
gendl__
I never actually thought about that. So from a memory storage point of view, :my-package would be more space-efficient.
14:21:21
gendl__
... because these things actually get stored in fasls and in the code section of memory, right?
14:22:39
phoe
note that gensyms are GCable if used only temporarily, so even if you allocate more of them then they get cleaned by the GC
14:22:56
gendl__
I’m guessing intuitively that the difference would normally be negligible. But maybe it would be something fun to experiment around with on a rainy Sunday afternoon.
14:24:19
raeda_
pyc: I have a copy of LOL. The title refers to creating a closure: the lambda captures the let's environment
14:28:16
CL-ASHOK
gendl__: "he’s talking about using e.g. #:my-package in one place in code, then #:my-package again in another place." --> Precisely, since I would define it within (defpackage and then re-use it later in the package itself)
14:30:26
beach
CL-ASHOK: The main point is that (in-package #:my-package) is very close to (in-package "MY-PACKAGE") because IN-PACKAGE takes a string designator, so if the symbol is given, its name is used which is "MY-PACKAGE".
14:30:39
CL-ASHOK
beach and Xach: Wouldn't it be a good thing for the symbols to clash (hence interning them is good), since it forces less ambiguity when writing code? Perhaps its a question of how many programmers work on a project - a single programmer perhaps should intern his package name and a large group working together perhaps should not?
14:30:56
beach
But #:my-package looks less ugly, because you would typically use lower case when you define your package.
14:32:03
beach
CL-ASHOK: Whether you use an interned or an uninterned symbol has absolutely no effect on sharing.
14:32:42
beach
CL-ASHOK: The point here is not about semantics, but about the message you send to the person reading your code.
14:32:49
CL-ASHOK
beach: thanks, that's a good reminder. I remember reading that, but that explains it nicely
14:33:28
beach
CL-ASHOK: If you use an interned symbol, you may give the reader of your code the impression that the package of that symbol is somehow important in this context.
14:33:58
beach
CL-ASHOK: Maybe you have a tool that reads this code some other way than the compiler, and that tool requires the symbol to be in a particular package.
14:34:50
beach
CL-ASHOK: Yes, and you are telling your maintainer "by the way, it has to be the keyword symbol here, because the package is important".
14:35:37
beach
CL-ASHOK: But if you use #:my-package, you are telling the maintainer "Yes, this is a symbol, but since it has no package, I can't possibly take advantage of its package"
14:36:59
CL-ASHOK
beach: sorry to be obtuse, this I don't get "since it has no package, I can't possibly take advantage of its package" --> why would someone want to take advantage of the package?
14:37:32
beach
Maybe you have a tool (the editor?) that reads the code and requires it to be a particular package.
14:38:24
beach
"In this project of mine, all the arguments to IN-PACKAGE must be keyword symbols, because I have this tool that scans my code and extracts all those symbols"
14:40:35
beach
Programmers often forget that the compiler is frequently just one of many tools that might be reading the code.
14:40:39
CL-ASHOK
is there a search tool to find Q&A answered previously in #lisp (over the last many years)?
14:50:44
beach
Well, most of this discussion was about communication with the maintainer. The semantics of Common Lisp are much simpler than those of most languages.
15:13:44
jcowan
beach: Has anyone written either a denotational or an operational semantics for a large part of CL?
15:19:12
jcowan
Usually you do full macroexpansion and then provide the semantics of what's left. Format is another matter: arguably a different language altogether.
15:20:03
jcowan
In addition, some things like LET are treated as primitive in CL, but obviously need not be.
15:22:06
beach
Nilby: It's a tricky macro, and most implementations seem to use the (not so great) MIT LOOP.
15:23:10
Nilby
It's funny, recently looked at an old MIT LOOP and it seemed much more tractable than the current one in use.
15:45:39
lukego
jcowan: it's not a large part of CL but I've recently been digging into ACL2 and wow that's an amazing system that's very strongly Common Lisp flavored.
15:46:56
lukego
yeah I was surprised to find that it seems to be alive and humming along, always assumed it would be something archaic and dying
15:48:59
Nilby
So is sicl-loop ready such that I can load it on other implementations and put in a for-as-X clause for my pet generic sequence?
15:49:49
beach
Nilby: Yes, I think so. Xach has been using it to check for non-conforming LOOP constructs in Quicklisp projects.
15:50:25
jcowan
I admit that is awesome. (Most Schemes that have LLKs make sure they aren't identifiers by using #!key or the like.)
15:50:36
beach
Nilby: In fact, nothing bad happens to you if you just load it into SBCL. You will trip the package lock, but if you accept, then it just works it seems.
16:08:43
nij
Yeah sorry for my sloppiness in using the right terminology. I understand it creates misunderstanding when I do that.. I will be more careful.
16:14:12
dieggsy
so i much prefer quri, but it's someone else's codebase - what's the puri equivalent of quri:make-uri ?
16:17:01
pjb
nij: in that case, packages are named by strings. package operators use: - package designators, which are either a package (itself), or string designators designating a package name, or - string designators (to designate symbols whose names are also strings). String designators are either characters designating a 1-char string containing it, symbols (whose name designates string equal to it), or strings.
16:18:51
pjb
nij: because of this designator hierarchy, you can (defpackage #\A (:use "CL" cl :cl #:cl #.(find-package "CL") #| <-- !! |# ) (:export #\F "F" f :f #:f))
16:23:12
jcowan
pjb: What hair. I sketched out a runtime package system for Scheme once, and my first decision was to heave all that overboard and say that the argument to a package procedure is a package object, period.
16:26:48
pjb
jcowan: yes, but in CL, packages are used at read-time, which occurs usually at compilation-time, therefore we must be able to declare things about packages possibly before or while they are defined.
16:28:02
jcowan
That was another decision: don't attempt to integrate the package system with R[67]RS library system, which exists only at macroexpansion time.
16:29:19
jcowan
Another blocker is that there just isn't enough demand for a symbol/package system used at runtime.
16:46:43
dieggsy
josrr: you're exactly right, and now that you've said that it seems obvious heh. thanks!
16:58:28
Nilby
So I managed to make an sbcl un-killable, not even a zombie. Is there even any O/S that isn't crap?
19:30:02
nij
Hi beach! Which parts of COMMONDOC aren't you convinced yet? And, when you mean to parse dpANS, do you want the macro to stay as they are, or you don't mind if it's parsed with all macros unwinded?
19:57:17
sm2n
huh, this is kind of interesting. Apparently a researcher who was trying to make a formal model for OOP ended up reinventing generic functions a la CLOS independently via theory
19:58:56
sm2n
this was while trying to give a nicer foundation to more "traditional" class-based message-passing OOP
20:05:58
Nilby
pjb: it was for real stuck. no amount of -9 could kill it "D" status in ps. But I've given up unix and now I'm just gonna run Mezzano
20:07:45
Inline
while compiling sbcl on voidlinux, it's mostly either threads-impure.lisp or so or something relating to mutexes
20:08:25
Inline
not sure if the installed ones resolved that problem, while the git version still seems to have that problem
20:11:43
Inline
Nilby: when the exit codes are not ok maybe that's why it stalls instead of terminating cleanly
20:14:04
jcowan
pjb: even kill -9 does not work with a process holding a "short-term" lock such as a file. Normally that's okay, but if the open() is taking a long time (NFS especially, but also some Fuse file systems), you are SOL. Reboot.