freenode/#lisp - IRC Chatlog
Search
18:47:00
pve
although the project I'm thinking of refactoring is decently sized so I'm not sure how well the "clean compile + test" loop would work in practice
19:59:59
aeth
I set a rule for myself that I must M-x s-r-i-lisp and quickload verbosely and run any unit tests (if there are any) before pushing to the git origin. And on a few of the occasions where I've broken this rule, I've pushed broken builds. Now, of course, this won't catch every refactoring error, but it will catch the ones that the CI process will also catch.
20:00:04
aeth
But jackdaniel pointed out some other solutions that will address this particular issue without restarting... Although, I think maybe uninterning so it shows up as an undefined function and requickloading might work. Maybe.
20:00:48
aeth
I'm not sure if there's a way to detect stale macros and inline functions in the callers of something that has now been redefined.
20:02:16
aeth
I think in general, if you think inlining/macros are involved, you probably should requickload and hopefully ASDF handles the redefinitions properly, at least if you redefined via changing the source rather than directly in the REPL
20:07:10
aeth
For refactoring, there are two complicating factors that I'm aware of if you want to redefine things. Redefining packages (e.g. no longer importing something that used to be imported; adding imports is fine) and redefining structs (afaik this is because accessors might be optimized, so the inlining problem comes up again). These are the ones that SBCL sort of complains about. There might be others that are permitted by the standard.
20:08:25
aeth
And on implementations complaining about something, you have to test in CCL after refactoring because a lot of refactoring is doing things like moving things into constants, and CCL is picky about when its constants are evaluated, requiring you to EVAL-WHEN some DEFCONSTANTs.
20:21:23
pve
aeth: I'm ashamed to admit I restart my repl probably more often than most, I even have a key bound to starting a new repl and loading a session file
20:22:27
aeth
This is why I find it amusing when people don't think about the necessity of inferior-lisps in their CL Emacs clone designs. Nope, you'd still need one.
20:23:25
pve
and I often have this tool running in the background: https://github.com/pve1/system-watcher
20:27:39
aeth
I save practically every keystroke, and tests could take up to minutes. They probably all should, but I don't test enough.
20:29:48
pve
hmm yeah I save all the time too, and the feedback isn't instantaneous if there's lots of tests, but saving a file won't interrupt an already started test run
20:31:35
pve
I would have liked to have a red/green indicator in the emacs modeline, but don't know how to do it
20:33:36
aeth
Personally, I'd just have it retest every $interval as long as it has been modified, where $interval depends on the project (a huge library with lots of long tests vs. a tiny library with instantly-running tests)
20:37:16
aeth
You could even determine it auotmatically based on the first successful run of the tests, although some tests are rather random.
20:38:13
aeth
So e.g. retest every 5x the expected test length if it's short (e.g. 1 minute tests means retest 5 minutes) or 2x (e.g. 20 minute tests means every 40 minutes) if it's long, with a minimum of 5 minutes wait
20:38:21
pve
although simple, but annoying breakage like fuzzing with package exports gets caught while loading the lib/app, before the tests even run
20:42:41
pve
your approach is much simpler to implement, because getting asdf to tell me which files belong to a system and messing with inotify isn't very fun
20:46:03
pve
but I used to dread doing package work, like splitting a package up into smaller packages, or moving stuff from one package to another, or just renaming things
23:25:38
jason_m
Is there a simple way to build a wrapper around a function with optional arguments, preserving the lambda list and leaving the handling of optional arguments to the underlying function?
23:25:39
jason_m
E.g. I have a function (foo a b c &optional d e) and I want to write a wrapper around it with the same lambda list, (bar a b c &optional d e). bar should supply the argument d (or e) to foo IFF d (or e) was passed to bar. The best I can come up with is using supplied-p-parameters, but that feels verbose and tedious.
23:37:22
White_Flame
&rest and apply do contain that behavior, but yeah, they don't expose the same lambda list
23:43:02
White_Flame
if (defun bar (a b c &rest opts &optional d e) ...) were defined such that OPTS would encompass all the remaining params, that would help as well
23:45:32
White_Flame
however, (defun bar (a b c &rest opts &key d e) ...) does work to encapsulate the keyword args, just not optional
23:47:37
phoe
I mean, a combo of TRIVIAL-ARGUMENTS:ARGLIST + ALEXANDRIA:PARSE-ORDINARY-LAMBDA-LIST should be capable of constructing your wrapper lambda form
23:47:58
jason_m
phoe: I know the lambda list. My questions is more about how to call the underlying function.
23:49:04
White_Flame
the runtime overhead also is kind of dumb with those types of workarounds, even if hidden under macroexpansion
23:49:49
White_Flame
but switching to keyword params would likely still be direct and reasonable, if you can change your protocol
23:51:38
jason_m
Appreciate the tips. I'll have to play around a bit. But I wanted to make sure I wasn't overlooking anything obvious :)
23:53:51
jason_m
I'm trying to build a wrapper around a DB library. The underlying library's function for making a connection takes several optional args, like port for example. One solution for port would be that I define my own default and always explicitly pass port. I don't like that because I think it can be confusing. I'd much rather not pass port on if I didn't get it, and let the underlying library's default values apply.
23:56:50
White_Flame
in my opinion, losing the lambda list is not that big a deal. Just requires using documentation instead of the emacs minibuffer hint
23:57:10
White_Flame
(unless of course you rely on introspecting the lambda list and doing something funky, of course)
23:58:17
White_Flame
(defun wrapped-foo (a b &rest c-d-e) (apply #'foo a b c-d-e)) is a readability hack for that
23:59:51
White_Flame
of course, it doesn't reflect any future changes of foo's underlying parameters, but with library usage that should be pretty stable anyway
0:01:23
jason_m
Yes, if foo (the library) changes, I'll have to update my code. Not too worried about that.
0:04:52
White_Flame
lots of code has &optional (foo *default-foo*) scattered in multiple layers of calls
0:11:41
jason_m
Seems like maybe one could write a function that takes some kind of argument and value list... maybe an alist or a property list, and a lambda-list, and sorts it out returning a list matching the lambda list for the given arguments.
0:12:34
jason_m
But for now I'm going to use the (foo a b &rest c-d-e) approach you suggested to keep moving.
3:49:32
rig0rmor_
in general have a fairly new relationship with lisp and have been doing down the rabbit hole a bit
3:49:41
beach
I suppose you know that SICP is based on Scheme and #lisp is dedicated to Common Lisp? Though some people follow SICP but do the exercises in Scheme.
3:52:54
beach
rig0rmor_: Also, you need to know that SICP is for teaching people about general principles of how programming works. But nobody writes code like that in practice.
3:53:58
rig0rmor_
I think I'm mostly exploring an interest in programming language theory, and compilers at the lower-level of that spectrum
3:57:22
beach
rig0rmor_: And Common Lisp is an excellent choice for programming-language design. It was designed by some very smart and very knowledgeable people. They were able to push the language very far, while remaining withing the boundary that still makes it possible to write compilers that generate fast code.
4:00:02
beach
If you want a more, how should I say this, "orthogonal" code base, you may want to look into SICL, though, the system does not exist yet, in that there is no native executable to run.
4:00:50
minion
rig0rmor_: SICL: SICL is a (perhaps futile) attempt to re-implement Common Lisp from scratch, hopefully using improved programming and bootstrapping techniques. See https://github.com/robert-strandh/SICL
4:01:51
beach
Of course, you caught me during a major modification of many parts of the code base. We are extracting the management of global environments to a separate library, and we changed the signatures of all the generic functions in the process.
4:02:47
beach
I mean, I will end up with SICL in the end, but I am starting off with simpler stuff. :)
4:10:29
beach
rig0rmor_: Oh, and #sicl seems to be the preferred hangout for people interested in all kinds of aspects of implementing not only SICL, and not only Common Lisp, but Lisp in general.
4:21:35
johnjay
is the motivation to not have to use version 1.2 to compile 1.3 to compile 1.4 but just compile everything from a base source?
4:32:39
beach
johnjay: The entire system should be possible to build using any ANSI-conforming Common Lisp implementation plus the "Closer MOP" library.
5:05:39
markasoftware
any good RNG libraries that take an integer seed, so I can persist the seed to a file?
5:21:13
Alfr
markasoftware, if you only want to save and restore it, then you may simply print a random-state and read it back.