freenode/lisp - IRC Chatlog
Search
6:55:35
beach
Not bad, thanks. My favorite coauthor is coming over for lunch, and then we will work on our ELS paper submissions for this year.
7:00:38
madrik
I've got to the point where I can ask my system which client IP made how many connections; what domains has a given IP visited frequently; etc.
7:01:26
beach
We think this one is pretty much ready to go: http://metamodular.com/bootstrapping.pdf
7:05:19
madrik
In abstract, wasn't this one of the motivations in the birth of SBCL -- that its ancestor, CMUCL, had a rather involved bootstrapping procedure to build it?
7:09:37
beach
We are taking it one step further by bootstrapping CLOS first, rather than last, as is common with implementations that were started before CLOS was part of the standard.
7:13:25
beach
There is this widespread idea that bootstrapping has to be done from a subset of the language to the full language in well defined increments.
7:14:10
beach
But that is obviously not the case if you bootstrap on an existing conforming Common Lisp implementation. Because then, you already have the full language at your disposal.
7:14:53
beach
Having said that, I should add that the procedure for doing it is pretty involved, mainly because of the way that Common Lisp defines compilation differently from other languages.
7:31:30
beach
ACTION is guessing that madrik is thinking hard about going before answering his question.
7:56:58
beach
I suppose. I didn't check. It seems reasonable since TYPE-OF must call CLASS-OF or something like that for standard objects.
8:02:48
LdBeth
from Design Patterns: An object can have many types, and objects of different classes can have the same type.
8:05:18
beach
An object in Common Lisp can have many types, sure. In particular, that is the case for numbers.
8:06:24
beach
And I assume you meant the type of the instances of the classes that share only T as superclass.
8:12:24
LdBeth
I don’t know if CL use the same term, but predicate type is type defined by a predicate function
8:13:07
beach
DEFTYPE does not define a function, so it would not be a predicate type with that definition.
8:15:46
beach
TYPE-OF is defined as a function in Common Lisp. But, in general the type of an object is not a mathematical function, since it has several values.
8:52:00
heisig
What is the recommended way to pass additional initialization arguments to a custom generic function?
8:52:51
fiddlerwoaroof
The standard allows it: "Implementations can extend defgeneric to include other options. It is required that an implementation signal an error if it observes an option that is not implemented locally."
8:57:09
heisig
SBCL signals a simple-program-error at macroexpansion time when I supply an unknown option.
8:57:45
fiddlerwoaroof
Anyways, I think this might rule out user extension: http://metamodular.com/CLOS-MOP/the-defgeneric-macro.html
8:57:59
fiddlerwoaroof
"The arguments received by ensure-generic-function are derived from the defgeneric form in a defined way..."
8:58:48
fiddlerwoaroof
The rest of that page seems to specify how DEFGENERIC translates to ENSURE-GENERIC-FUNCTION but doesn't really say anything about extra init args
8:59:28
heisig
fiddlerwoaroof: Yes, I have a custom generic metaclass. (My goal is to implement sealable metaobjects: https://github.com/marcoheisig/sealable-metaobjects )
9:00:24
heisig
Things look good, so far. But I would prefer another mechanism for supplying initialization arguments than hidden use of special variables.
9:05:57
heisig
Yes, I will probably go for a custom macro DEFINE-SEALABLE-GENERIC-FUNCTION that expands into DEFGENERIC plus some further initialization.
9:06:42
fiddlerwoaroof
The other option (which would probably be a lot of work) you could also have something like defgeneric* that has a defined mapping between unrecognized options and calls to accessors?
9:06:52
beach
note to self: For WSCL, investigate the possibility of extending DEFGENERIC with additional options.
9:09:17
madrik
beach: Okay. It just seemed a very comprehensive system, with a compiler, an interpreter, /and/ a byte-code subsystem.
9:10:51
beach
madrik: I think "comprehensive" also means "highly redundant", thus requiring additional maintenance for which no manpower is available.
9:12:06
heisig
fiddlerwoaroof: defgeneric* could work. Maybe one could supply all excess options as an additional plist to ensure-generic-function. I will think about it.
9:12:52
fiddlerwoaroof
heisig: a defgeneric* macro would also be useful on its own, for other people that want to do similar things
9:15:28
fiddlerwoaroof
I generally make sure as much of my code as possible runs on at least sbcl and ccl
9:15:53
fiddlerwoaroof
And, on Macs, ccl has better integration out of the box with Objective-C and Cocoa
9:19:31
heisig
fiddlerwoaroof: Here I go, developing a utility library for a utility library of a module of a Lisp implementation on which I want to develop a utility library for parallel programming :D
9:20:31
fiddlerwoaroof
I occasionally write "real" code, but mostly I write one or two stages away from the problem I want to be working on.
9:21:06
fiddlerwoaroof
Most recently, I've been working on a way to treat an emacs buffer as an output stream
9:21:27
madrik
Oh, just for fun, I was writing a naive function to compute e, when I came to point where I thought, "Why isn't there a MULF by analogy to INCF?"
9:24:51
beach
madrik: I recommend you read the book On Lisp that discusses macro definitions at length.
9:25:21
fiddlerwoaroof
It's almost always better to use abstractions like this because they hide the noise and just let you express your intent
9:25:49
loke
You can do the same using DEFINE-SETF-EXPANDER, but in this case the former is much easier.
9:35:13
loke
madrik: It doesn't have to be that long: (loop for i from 1 to n for e = #1=(1+ (/ n)) then (* e #1#) finally return e)
9:40:15
heisig
shka_: Somewhat. But if it would be like final, I would have called it sealed-metaobjects. The idea is that you can manipulate and, most importantly, subclass sealable metaobjects until they are explicitly sealed.
9:45:14
heisig
The idea is that you get calls with built-in (or sealed) instances as fast as regular +, but that you can still extend such a generic function it in the general case.
9:46:05
shka_
heisig: just realized that i made my code resistant to this form of optimization few months ago ;-)
9:50:53
loke
heisig: That could be done even with the current spec. What is simply needed is a way to uncompile code. The JVM does that, and nothing wuld, in theory prevent the same for being done in Lisp.
9:54:56
heisig
loke: I am not sure about that. If you allow, e.g., :around methods on built-in addition, you will have a bad time.
9:56:57
loke
Also, the pause times wouldn't be overly bad, sicne you wouldn't be recompiling the functions until they are called (or, as is the case with the JVM, until the function has been called more than N times (configurable, with a default value in the thousands))
11:25:26
no-defun-allowed
As far as I know, calculus is reserved for derivatives and integrals of expressions.
11:28:27
dim
a group is like (N, +, 0) for integers (naturals) with addition and neutral-element zero, with well defined meaning such as commutativity, associativity etc
12:33:03
r13l
i’m working on using lisp to replace shell scripts, so am taking a look at e.g. INFERIOR-SHELL &c. man-oh-man do i wish that the standard had gone with case-preservation. oh well, i’m sure that it made sense in the 80s, and by the 90s they were stuck with it
12:35:17
shka_
r13l: i think that idea back in the day was that interactive systems should be case insensitive because this makes them more convinient
12:39:05
r13l
i think it’s because some systems back then were still caps-only. makes it a chore to use symbols to represent strings intended for the shell. either one leaves the case as-is (bad, because to a first order of approximation _nothing_ on a Unix system is uppercase); one downcases everything (bad, because a few things _may_ be uppercase); one inverts (bad, because the reader already had a chance to invert); or one plays with special
12:39:05
r13l
read-macros (bad, because then it uses a character the user might have wanted to use).
12:40:02
r13l
i look at scsh, and i’m so envious that it could just preserve case. and use | & |+ (if you’re case-preserving, there’s a lot less need for multiple-escaping …)
12:41:42
jackdaniel
nb: you may have case-preserving reader without much hassle by modifying readtable-case
12:42:34
jackdaniel
*but* then you'll need to call things from the cl package and "ordinary" librarires like that: (CL:LIST 1 2 3) ; (or if you "USE" CL package, then (LIST 1 2 3)
12:43:20
r13l
yeah, but then one has to write lisp symbols in upper-case, which is a pain (have to hold down the shift key) and also difficult to read. i think it’s ugly, too, but that may just be me
12:44:06
r13l
i really like allegro’s modern mode, but sadly it doesn’t seem to have caught on elsewhere, e.g. with SBCL
12:47:25
jackdaniel
you may set this readtable-case globally and it will most likely work with most libraries
12:48:28
jackdaniel
as of CL symbols: writing a piece which creates |common-lisp| package and creating symbol-macros which refer to COMMON-LISP symbols seems like a dozen of minutes hack
12:49:15
jackdaniel
or, even better, utility which takes *any* package, creates its evil twin in lowercase and having there lowercase symbol macros which reflect original upcase symbols
12:54:44
r13l
yeah, and e.g. one would want (echo t) to return "t", not "T" — but one would also want "t" to be read as T, in order for e.g. (find-class 't). corner cases are fun
12:55:45
r13l
https://franz.com/support/tech_corner/modern.mode.lhtml gives good details on the approach franz took
12:56:43
r13l
not in this case, where (echo t) is supposed to be interpreted as a call to a Unix binary
12:58:33
r13l
e.g. (my-special-read-from-string "(echo t)") → (|echo| |t|). (run '(|echo| |t|)) then searches PATH for a binary named (symbol-name '|echo|) and then calls it with arguments (mapcar #'symbol-name '(|echo| |t|))
13:07:05
r13l
e.g. https://pastebin.com/m8iWpFDp (there’s an example of what scsh would look like; getting to lisp version is … tricky). oh well, i’ll probably just copy INFERIOR-SHELL and downcase symbols. it’s probably the least bad solution
13:08:15
jackdaniel
you have a special reader macro which switches you to sh syntax (and vice versa)
13:10:19
dim
I think a scsh comparable tooling already exists in CL, along with asdf/uiop facilities, by Fare again, right?
13:11:03
r13l
ooh, i hadn’t found SHELISP or CLESH. not a huge fan of shell syntax (i like that INFERIOR-LISP & scsh use s-expressions to represent commands), but still — really cool!
13:20:02
r13l
oh, no worries! thanks for the link. the big problem i had just using INFERIOR-SHELL is that — for some reason — programs it launches don’t get killed when their parent is killed, so e.g. typing C-c kills my lisp process but not the long-running command _it’s_ running (which is weird, because i’d expect them to all be in the same process group). which sent me down the rabbit hole …
13:23:43
r13l
yes, but e.g. a shell script does the right thing here. i haven’t (yet) read the source of e.g. zsh to see, but i imagine that it installs a SIGINT/SIGTERM handler which signals each child process, then terminates (so the children would only be orphaned if that handler isn’t run)
13:23:46
jackdaniel
you may also keep child processes in your collection and on sigint send them the same thing before exitting
13:25:09
r13l
yeah, i’m doing that now. i use UIOP:LAUNCH-PROGRAM instead of UIOP:RUN-PROGRAM, and install a signal handler (thanks to your advice yesterday) which kills each running process. i guard the list of running children with SB-SYS:WITHOUT-INTERRUPTS
13:25:53
jackdaniel
I've looked at UIOP:*-PROGRAM source code a few times and each time I was horrified
13:25:54
r13l
as you can imagine, my simple little script has gotten a bit unwieldy, hence my desire to find or write something which abstracts away some of the messy details *grin*
13:27:31
jackdaniel
Xach: I sometimes use external-program (which is also a simple wrapper around implementation native run-program)
13:27:49
jackdaniel
UIOP puts some abstraction on /everything/, including streams and files, even if implementation handles them better than UIOP
13:28:01
r13l
it’s actually a dirt-simple backup script: sets up some environment variables, runs borg to backup ~, runs notmuch dump | borg to backup my email tags, then runs borg backup twice. i’ve spent _way_ more time lispifying it than i should have, but … it’s fun *grin*
13:28:45
Xach
I have some build stuff that has to run git in a lot of different ways and it is really nice to be able to do it with lisp functions and macros instead of shell scripts.
13:29:35
Xach
And sometimes I feel like people want to bind to libraries to work like that, but I have had good success and have been very happy with run-program to get started. And much of the time it's more than enough for ever.
13:30:31
Xach
i had a system that processed thousands of images per day with imagemagick and i just spawned "convert" - no need to mess with binding to libmagick or anything else.
14:56:35
shrdlu68
"Quick test: if you create a new namespace and import another file within that namespace, do its contents end up in that namespace?"
15:04:04
dlowe
and packages aren't hierarchical in CL, so importing another file "within" that namespace doesn't make any sense
15:21:58
pjb
shrdlu68: if your file contains (cl:defun cl-user::foo (cl-user::x) (cl:+ cl-user::x 42)) and assuming no foul play with the *readtable*, then you can set the *package* to any package, loading the file will always read the same sexps!
15:22:40
pjb
shrdlu68: Similarly, as soon as the file contains a toplevel in-package form, it controls the package in which the following unqualified symbols are interned.
15:23:26
pjb
dlowe: usually, people write (in-package "BAR"). But if FOO::IN-PACKAGE is not CL:IN-PACKAGE, (in-package "BAR") can have different effects.