freenode/#lisp - IRC Chatlog
Search
2:06:12
sjl
In hindsight, this (for ... matching ...) iterate driver may have been overkill, but at least it'll help make advent of code input parsing less tedious https://hg.sr.ht/~sjl/cl-losh/browse/default/src/iterate.lisp#L890
2:11:58
_death
sjl: last year I started writing utilities for AoC as well.. since I don't like to use regular expressions in code, back in 2018 I came up with this: https://gist.github.com/death/4ed89bf10404f5c71f1fb8f2a95a0f13
2:12:46
_death
incidentally, "slhelper" stands for "(Santa|Satan)'s Little Helpers" .. regexes in names are fine :)
2:18:43
_death
btw I found another bug, this time in cffi-libffi.. (defcfun foo :string) will try to foreign-string-to-lisp the pointer to the string pointer instead of the string pointer itself... other types may also have this issue, but I fixed it for foreign-string-type at least
2:21:46
_death
LdBeth: yes, a C string is a pointer to char.. cffi type :string automatically converts between foreign and lisp strings
2:32:29
pjb
LdBeth: I use (merge-pathnames (make-pathname :directory '(:relative) :name "ccl-init" :type "lisp") (user-homedir-pathname)) so it works everywhere!
2:34:35
pjb
LdBeth: a string is a vector of character. It's way more sophisticated than what C proposes.
2:35:19
no-defun-allowed
'<char>' is just syntactic sugar for the integer with the same value as the character's codepoint.
4:57:38
White_Flame
is there some sort of asdf extension out there that lets you place dependencies inside the individual .lisp files instead of in the .asd?
5:58:16
anlsh
When I do (ql:quickload :alexandria) I get the following error: The name "ALEXANDRIA.1.0.0" does not designate any package.
6:41:07
no-defun-allowed
ACTION waits for fully inferred systems, where hypothetically any time an undefined variable or function is used, its definition is searched for and the file containing its definition is loaded
8:22:40
beach
You would have to do it yourself, like (unwind-protect ... (let ((old (fdefinition ...))) (setf (fdefinition ...) #'...) etc.
8:32:34
reepca
aye, just a little tedious to go around swapping out (read-byte ...) with (funcall *read-byte* ...) because I didn't read and memorize the full spec before I started writing
8:33:22
Shinmera
also, it seems to me that you would very likely be better off with GFs than dynamically bound functions.
8:33:51
Shinmera
as in, define the generic function protocol, then pass around the object that implements it.
8:33:58
anlsh
How do I get frame restarts working in sly/slime? Every time I press the "r" key I just get a message about the frame being compiled, and I'm not sure what to change to fix that
8:35:24
reepca
does it work to have a generic function with the same name as an existing CL function?
8:37:55
specbot
Constraints on the COMMON-LISP Package for Conforming Programs: http://www.lispworks.com/reference/HyperSpec/Body/11_abab.htm
9:10:17
pjb
reepca: (defvar *foo*) (defun foo (&rest args) (apply *foo* args)) (defun g () (foo 1 2 3)) (let ((*foo* (lambda (&rest args) (reduce '+ args)))) (g)) #| --> 6 |#
9:10:41
ck_
Shinmera: you're running irclog.tymoon.eu, is that right? Are you open to a small feature request?
9:11:55
ck_
I'd sometimes like to switch channels at or around the timestamp I'm currently looking at
9:14:21
pjb
White_Flame: it has probably bit-rotten a little, since I don't use it anymore. Putting dependencies in asd files is better.
9:14:34
Shinmera
I could maybe turn the channel header into an option list instead to do the switching. I'll think about it.
9:14:45
ck_
well, the first thing I looked for was a time input field at the channel view, to navigate to a point in history that way. I'll just add a bookmarklet to get there quicker
9:14:50
pjb
White_Flame: but the principle applies: scan the files to build the dependencies yourself, and generate an asd file.
9:15:42
Shinmera
ck_: The software running is open source too, so if you have time you could have a go at fixing it yourself. https://github.com/shirakumo/chatlog
9:17:18
Shinmera
Time input did exist in a previous version, but it became too cluttered, especially for mobile, so I removed it in the streamlining process.
11:10:22
boeg
So I'm trying to figure out how systems and packages works, and I've created a package.lisp now and a *name*.asd. Now, I normally just use sly in emacs to run my common lisp and manually use quickload to load libraries, but now I have defined a dependency in the asdf file, so my question is, how do I use this in sly so it takes care of loading things defined with asdf?
11:12:33
pjb
boeg: systems define a set of files, and their dependencies, so that asdf can compile and load them in the right order.
11:13:18
pjb
boeg: those files may contain in-package forms, so that their symbols are interned in those packages.
11:13:49
boeg
So package.lisp contains defpackage and then in a another file i have an in-package call for the package defined in package.lisp
11:13:58
pjb
boeg: this may be packages defined in a file of the system, or not. You could (defun cl-user::foo () 'foo) thus defining a function named by a symbol interned in the cl-user package, for example.
11:14:40
pjb
boeg: so if you want to define your own packages, and put them in a package.lisp file, this file needs to be loaded before the other files are compiled or loaded, so their in-package forms will find the packages you defined in the package.lisp file.
11:14:58
pjb
So for each file, you will have a dependency such as: (:file "foo" :depends-on ("package" …))
11:15:46
pjb
boeg: remember, asd files are just like Makefiles, they define dependencies between your files (and also with other systems).
11:16:09
pjb
boeg: this is a system dependency. You define it with :depends-on in the defsystem form.
11:16:41
pjb
Once this dependency is established, your files can access directly anything that is defined by those systems, since they will have been loaded before the current system.
11:17:14
pjb
boeg: if you make your asd systema vailable to quicklisp (eg. putting them or a symlink in ~/quicklisp/local-projects/ ) then you can just use quicklisp for your system like for the others.
11:17:33
pjb
The advantage of using quicklisp, is that if you're missing a dependent system, quicklisp will download and install it automatically.
11:18:19
boeg
oh, so I make a symlink in ~/quicklisp/local-projects/ to my .asd file that has a dependency on split-sequence
11:19:05
pjb
No need to loald the .asd file directly or any other file. quickload will do everything.
11:20:33
boeg
pjb: does it matter how deep the .asd file is relative to the symlink? Could I for example symlink to ~/projects where the .asd file is in ~/projects/../*.asd ?
11:21:29
pjb
in some cases, quicklisp doesn't discover them immediately. You can force it with (ql:register-local-projects)
11:25:20
boeg
I load my system, seems to be fine, then I load a file I'm working on and call a function just like (my-function) which usually works but now it doesn't
11:26:13
pjb
You must use the name of the function, which is a symbol interned in some package. You need to know this package.
11:26:42
pjb
If you have a in-package form before the form where the name of the function is interned, then it's interned in that package.
11:26:47
boeg
so the package is named ... well i have (in-package :aoc2019.day06) at the top, and function is called day06
11:27:47
pjb
perhaps you exported "DAY06" from the package named "AOC2019.DAY06", in which case you can use: (aoc2019.day06:day06) or (use-package :aoc2019.day06) and (day06)
11:28:50
pjb
For example, you could define a asd system aoc2019 dependent on all the aoc systems, with a aoc2019 package that would use all the aoc2019.day?? packages, so that (in-package :aoc2019) you could call directly all the (day01) .. (day31) functions.
11:29:07
boeg
something is weird though, if I remove the "in-package" and do as I use to, my function gives one result and if I go about it with asdf and so on, call it with (aoc2019.day06::day06) it gives a completely other result
11:29:36
pjb
boeg: if you're lost you can use (let ((*package* (find-package "KEYWORD"))) (apropos "day")) to find what package the day symbols are interned in.
11:30:04
pjb
boeg: your functions may depend on the run-time package if they use READ or INTERN etc.
11:30:27
pjb
boeg: it's not a good idea in that case to let the run-time package up to the user. You would have to bind the *package* at run-time.
11:31:49
pjb
You may also depend on other variables such as *print-…* or *read-…*; you can get a specific setting with (with-standard-io-syntax …) or otherwise code to avoid depending on them, or set them to specific values.
11:32:12
pjb
For example, (setf *read-base* 8.) or (setf *read-base* 16.) could break a lot of program using numeric input…
11:32:50
boeg
but I don't understand ... How are are the functions loaded differently depending on if I use asdf or just manually load my .lisp file?
11:32:58
pjb
If your specifications specifies base ten, then your program should contain a (let ((*read-base* 10.)) … (read) …)
11:34:09
pjb
boeg: they're not loaded differently, they're loaded with load, in the current *package* and *readtable* by default. Perhaps asdf sets the current *package* to something specific different than your current *package* in the REPL, but it's up to your files to contain in-package forms to specify which *package* must be used to intern the symbols in your sources.
11:35:26
pjb
For user input, you can (delete-package "MY-RUNTIME-PACKAGE") (make-package "MY-RUNTIME-PACKAGE" :use '()) at the start of the program to clean things up.
11:36:47
pjb
It may be a good idea to have different packages for the program and for user's symbols.
11:40:48
pjb
you could use a temporary package named AOC2019.DAY6.PLANETS-XXX to read the planet names.
11:42:33
boeg
if I just wanted to have intern use the current aoc2019.day6 package, i should just give the second argument "AOC2019.day6" ?
11:42:39
pjb
alternatively, since you need to intern the planet names only for EQ hash-tables, etc, you could just use make-symbol instead of intern.
11:43:38
pjb
planet names are not program identifiers. They don't belong to the package where you intern your program symbols.
11:44:12
pjb
Well, if you use make-symbol you will have to unify them yourself, so better use a temporary package for the planet names.
11:45:17
boeg
just four different strings, so it wasn't gonna bloat the "symbol registry" but yeah, probably a bad decision
11:45:20
pjb
You will have to intern them in a equal or equalp hash-table to find them again (there are several occurences of a single planet name).
11:47:39
pjb
create a hash-table, setf gethash the strings, delete the hash-table, vs create a package, intern the string, deletel the package…
11:48:01
pjb
The only thing is that you want to generate a unique package name in case your program is run in parallel in different threads.
11:48:31
kmeow
what's the right way to export a struct from a package? I'm missing the slot symbols for its constructor
11:49:23
pjb
(let ((*planet-package* (make-package (make-unique-package-name "AOC2019.DAY06.PLANETS-") :use '()))) (unwind-protect (do-something) (delete-package *planet-package*)))
11:50:56
pjb
see for example: https://github.com/informatimago/lisp/blob/c98c1b33fe781bb69d638cfbad4bfa6a241f33f6/common-lisp/interactive/interactive.lisp#L308
11:51:40
pjb
Of course, to ensure thread safety a lock would be needed while generating the unique name.
11:52:09
pjb
in the case of mkupack, it's an interactive function, so we assume the user doesn't call it from threads.
11:53:19
boeg
I could simplify the code now that I understand objects better, get it with `elt` and use case to match on it
11:56:02
pjb
use-package is for compilation-time (or the REPL). not for run-time. For run-time, you would just bind *package* (let ((*package* my-runtime-package)) (read))
12:08:59
_death
kmeow: you cannot export a struct from a package.. all you can do is export symbols, so export make-struct, struct-foo, struct-bar, etc.
12:14:13
kmeow
for something like (defstruct astruct a b c) I've been using (make-astruct :a val1 :b val2 :c val3)
12:14:33
_death
those are usually keyword symbols (i.e. symbols in the keyword package).. symbols in the keyword package are automatically exported, so they can use them from anywhere (i.e. they are global)
12:19:03
_death
if your struct has a state slot, the default constructor function will take a :state keyword argument