<mountainman1312>
howdy everyone. I'm rather new to common lisp. Trying to build an executable using a Makefile, and it's not going well. I have followed the cookbook to design a simple system. When I try to "(ql:quickload fash)" it says "The variable FASH is unbound." To avoid clogging chat here I've pasted file contents and the output of the make command at https://pastebin.com/LShrj0bx. Any help is appreciated :)
<ixelp>
Need help with CL/ASDF building executables - Pastebin.com
<mountainman1312>
I've tried to add the path to this project to asdf:*central-registry* but that didn't seem to work either
pfdietz has quit [Quit: Client closed]
<beach>
mountainman1312: QUICKLOAD takes the name of a system. If "fash" is the name of the system, you may want to give the string "fash" to QUICKLOAD as opposed to the variable named FASH.
<beach>
mountainman1312: QUICKLOAD is a function, so the arguments are evaluated before the function is called.
<beach>
mountainman1312: Also, I recommend you join #clschool, which is specifically for newbie questions.
<mountainman1312>
beach: Thanks! Now I'm getting new errors so that seems to have fixed that particular issue. And thanks for the channel, I'm joining now :)
<beach>
Sure.
reb has quit [Read error: Connection reset by peer]
reb has joined #commonlisp
akoana has quit [Quit: leaving]
anticomputer has quit [Remote host closed the connection]
anticomputer has joined #commonlisp
Pixel_Outlaw has quit [Quit: Leaving]
shka has joined #commonlisp
wacki has joined #commonlisp
donleo has joined #commonlisp
alcor has joined #commonlisp
mishoo has joined #commonlisp
Lord_of_Life has quit [Ping timeout: 246 seconds]
Lord_of_Life has joined #commonlisp
zxcvz has joined #commonlisp
pve has joined #commonlisp
zxcvz has quit [Quit: zxcvz]
metsomedog has joined #commonlisp
Gleefre has quit [Ping timeout: 256 seconds]
elderK has joined #commonlisp
<elderK>
Hey guys!
<elderK>
Where is the best place to ask general questions about like, how to organize things and name stuff? I have a lot of mundane questions.
<elderK>
Is #clschool the best place to ask these questions?
<Ashy>
I don't know but I'm also interested in that
<Ashy>
coming from rust where cargo is really nice for creating a new project repo that's laid out in "best practice"
<Ashy>
I'm not sure what the equivalent for commonlisp is yet
<elderK>
Ashy: I'm finding it difficult coming from languages that kind of force you more strongly.
<elderK>
If you know what I mean.
<elderK>
For me, it's from C and C++: It's the small things that I find are the most problematic. Details such as how we should name accessors for class slots. Or, how many packages we should use. How do you decide whether you should use one package or many? I imagine it's a pragmatic thing.
<metsomedog>
Ashy: most projects use ASDF for "systems" (collection of packages + external dependencies), defined in some file with .asd suffix, and some variation of package.lisp to define the packages themselves.
ndanilov has quit [Ping timeout: 246 seconds]
<elderK>
I've read advice that I should treat all accessors as part of a protocol and this makes sense. But, sometimes, the accessor is really just an accessor and I'd prefer a short name for convenience. But then, that name will collide with possibly different accessors with the same name. So, I could prefix things or change the accessor names to be different but then, you know, things get much more
<elderK>
wordy.
<elderK>
I'm finding "stupid details" like that to be giving me the most trouble.
<elderK>
Ashy: How familiar with packages are you? Are you just starting out or are you trying to find a style that works best for you?
<metsomedog>
elderK: it's usual to prefix functions with % if they are only for internal use in the package
<Ashy>
elderK: just starting out, I've read through PCL and started playing with ciel a little bit
<metsomedog>
people at #clschool are very helpful for beginner questions btw
<elderK>
Ashy: Then you'll definitely want to listen to metsomedog. There are kind of two levels to think about, the "system level" and the "package level." You can think of a system as bundling up an entire project or library. When I started out, I thought of systems as being analogous to a makefile.
<elderK>
Packages are a lot like namespaces in C++ but also very different: Packages are just a container for symbols. Symbols, of course, can represent various things.
<elderK>
metsomedog: In my case, the accessors aren't truly specific to one package - they are intended to be used by other packages, too. Say, I have some classes representing AST nodes. I want the packages that manipulate those nodes to have access to those things but I don't want those accessors (or classes) to be visible everywhere. I also don't want to lump in all the "transformations" into the AST
<elderK>
package, either, because I may be transforming between different hierarchies of AST classes. Say, one for the input language (a Scheme like) and one for the IR, and another for the target (x86).
<elderK>
So far, I've experimented with system-per-directory, package-per-file and just the standard "one system, one big package" approach.
<elderK>
Have to say, package local nicknames are pretty awesome, too. They make this a lot less painful.
<metsomedog>
elderK: I don't understand. If they are used by many packages, they are part of the public API no? Also the other packages can prefix the accessor with the package it's originally defined in. Remember it's just a generic function.
<pve>
elderK: which approach do you like best?
<elderK>
metsomedog: Here's a bad example but, one that I hit experimenting: I have a class called language that has a slot called %name which I want to access conveniently as (name some-language). I might also have an AST class called say, binding that has slots %name and %value and I'd like to access those via (name binding) and (value binding). I may be using instances of language and binding at the
<elderK>
same time.
<elderK>
My solution here was to use either class-slot style or just give less generic names like bound-name and bound-value.
<elderK>
The class-prefix style is difficult because I find I hit the "margin" a lot faster and some times, it's not easy to resolve. I'm not sure whether anyone else cares about the 80 column max but I try to stay within that. I'm open to challenging that view, though.
<elderK>
pve: I'm not sure so far. package-per-file comes with a lot of boilerplate and repetition. I do like that it automates a lot of what you'd do if you had a bunch of systems (system per directory), though.
<elderK>
systsem-per-directory is more discoverable, I find. Easier to find where everything is.
<elderK>
It's still a toss up for me :)
<pve>
elderK: I see, thanks.
<elderK>
pve: I'd probably enjoy package-per-file more if I used uiop:define-package but I try to stick to the "core CL" stuff.
<metsomedog>
elderK: I guess :accessor name or :accessor language-name could work? Afaik there's no problem with 2 classes having the same accessor name (it's just a generic function)
<elderK>
metsomedog: Indeed but it becomes a problem if the classes are defined in different packages, right? In order for those accessors to be methods on the same generic, we'd have to define a protocol somewhere else that says "name is a generic function."
<elderK>
But then how do you document that? "Return the name of a named thing?" :D
<elderK>
For languages, return that languages name. For a binding, return the name of the variable it bounds. For a variable reference, return the name of the variable we are referencing. So, you'd have better documentation in the methods rather than the generic.
<metsomedog>
elderK: Sorry I don't have enough experience to answer this well.
<Ashy>
metsomedog: elderK: cheers
<elderK>
metsomedog: Same for me :)
<elderK>
metsomedog: Do you limit your line length? What is your limit? Are you strict about it?
<elderK>
Ashy: No problem :)
<metsomedog>
I use 100-120 but idk about best practice. I think 80 colums is too short in 2024. It makes the code less readable with arbitrary newlines imo. Tho it's nice to newline to make reading the code more structured
<elderK>
metsomedog: Definitely finding 72 or 80 hard. Say you have the functio name "partially-evaluate" and you are using accessors with names like "let-bound-name" or "application-operands." You hit the margin *fast*.
<elderK>
Sure, maybe these names are too long but that leads back to the questions above.
<metsomedog>
elderK: In my personal projects I have set the emacs setting to 100 (if you press M-q it will format the lines), and I allow up to 120 characters if it makes the code more readable
<elderK>
metsomedog: Do you vertial split your screen often? I use Vim myself and I am very fond of looking at two files side by side.
<elderK>
When I was younger, I could use a tiny font and so width didn't matter so much. These days, I need the font to be larger and it restricts how wide my lines can be.
<metsomedog>
Yes I use 2 vertical splits on 1080p display or 3 vertical splits on 1440p. 100 characters does not extend beyond the split in this case with my font size.
dmgk has joined #commonlisp
mishoo has quit [Ping timeout: 252 seconds]
<elderK>
metsomedog: Interesting. What font and point size?
<elderK>
I use Iosevka Medium Extended at 14 or 16pt.
<elderK>
I miss being able to enjoy the classic X11 "Fixed" bitmap fonts. These days, they're just too darn small
<metsomedog>
elderK: IBM Plex Mono, apparently size is 16 pt but not 100% sure (this is on 1080p laptop)
<elderK>
Nice choice: I used to use that, too.
<elderK>
I'd be surprised if you used 16pt and had two panes open, side by side, at 100 characters.
<elderK>
Do you show line numbers?
<metsomedog>
No, I have minimal clutter. In Emacs only the mode-line contains that info. I found the line numbers take way too much space, especially in Emacs because they display in each buffer
<elderK>
I wish I could see a screenshot :D
<metsomedog>
Sorry don't want to upload anywhere :p but it's very simple. Basically stock emacs with gruvbox, the aforementioned font, and (menu-bar-mode -1) (scroll-bar-mode -1) (tool-bar-mode -1)
* elderK
nods
<elderK>
I use i3wm. 1920x1080. Not sure what my DPI is but I will check.
<elderK>
96dpi.
<metsomedog>
Ahh. I just use stock XFCE atm. Used to use StumpWM but too much work to get a usable modeline.
<metsomedog>
Who needs tiling when Emacs exists anyways?
<metsomedog>
(lets continue convo in lispcafe as I see you are active there as well, guessing people don't want spam in this channel)
semarie has quit [Remote host closed the connection]
semarie has joined #commonlisp
* elderK
nods
<elderK>
Hopefully someone gives me more info on naming and packages and suchlike, though :)
semarie has quit [Remote host closed the connection]
semarie has joined #commonlisp
semarie has quit [Remote host closed the connection]
semarie has joined #commonlisp
zwr has quit [Read error: Connection reset by peer]
zwr has joined #commonlisp
<pve>
elderK: There is another alternative: You can use package-inferred-system, but still adhere to, say, one-package-per-directory, i.e. (in-package #:my-big-package). Additionally, the file-specific package can be used as a "private" namespace, if necessary.
<elderK>
pve: How would this work? With package-inferred, doesn't each file need its own package?
<elderK>
Unless you mean re-exporting into a higher-level package (directory level) just the intended public things.
<elderK>
That'd be where uiop:define-package shines, right? import-reexport and stuff?
<pve>
elderK: each file has its own package, but you can still (in-package #:some-other-package)
<elderK>
pve: Thanks! I didn't think of that!
<pve>
elderK: no problem
<elderK>
Too bad we can't have "per file local nicknames" :P
<beach>
elderK: You should name accessors for class slots independently of the fact that they are accessors for class slots. They should be named as natural operators on the instances of the class.
<beach>
elderK: Client code should not have to distinguish between operators that happen to access a slot and more complex operators. And you should not have to rename slot accessors if you decide to remove the slot and use some other way to implement the operator.
<elderK>
Hey beach! That definitely seems the best way.
<elderK>
Keene's book suggested the same, too :)
<beach>
elderK: For packages, I divide my software into "modules" that are like the modules of any other language, except that Common Lisp does not have linguistic support for modules. I then use a sub-directory of the OS host for a module, and I use (at least) one package for that module, and one ASDF system. You can look at lots of my software and you will see the same pattern.
cage has joined #commonlisp
cage has quit [Excess Flood]
<elderK>
beach: I have been - I learned the package-per-directory / system-per-directory approach from cluffer.
cage has joined #commonlisp
<elderK>
:)
<beach>
Excellent!
<elderK>
I have so many mundane questions. With CL, it seems common to define many classes in a single file, maybe also with generics and methods, maybe not. In C++, it's common to have a file pair per class. I am trying to give up the C++ thinking but I am finding it hard.
amb007 has quit [Ping timeout: 248 seconds]
<elderK>
Also, how to wrap parameter lists: I try to give parameters meaningful, unabbreviated names but then, the line is very long so I have to split. If I have say, specialized parameters for a method, it can get difficult.
ndanilov has joined #commonlisp
<beach>
elderK: It is safe to have a generic function NAME that can take instance of totally different classes as arguments. In fact, you can have a NAME-MIXIN class that contains the %NAME slot and which is the specializer of the NAME method.
<elderK>
beach: I thought of that approach: Have a "nameable" protocol as it were. Where can I learn more about mixins? :)
amb007 has joined #commonlisp
<elderK>
From what I've read: A mixin is a class that introduces some stuff, but is independent of the classes that might incorporate it?
<elderK>
Say, you gain access to new around/before methods, or new generics.
<beach>
I think Keene's book mentions them. It is just an ordinary class, but it is often suffixed -MIXIN. Then it is the superclass of all classes that have a name.
Gleefre has joined #commonlisp
<beach>
Yes, it is its own independent class, but with it, you avoid duplicating the slot and the method.
<elderK>
Is it common to factor slots out in that way?
<beach>
Yes, that's what it is for.
<elderK>
Ah, thank you :)
<beach>
Slot or any other functionality.
<elderK>
I think mixins will make a lot more sense to me now.
<beach>
Search for "-mixin" in code repositories.
<elderK>
I have a *lot* of other-language-baggage to dump. I have to say, it's kind of interesting to see first-hand how using one language for so long really can shape how you think of things.
<beach>
I understand. It's a well known phenomenon.
<elderK>
I wish I could, like, overcome that more quickly. I'm studying a lot of code, pretty much every day I cannot type for long or am not at work. Reading, too. I guess you just can't rush things.
<elderK>
Thanks beach :)
<beach>
elderK: If you have a NAME accessor for two classes in different packages, there is absolutely no problem, because they are then different functions with different names: P1:NAME and P2:NAME.
<elderK>
beach: Right but if you :use those packages at the same time, you would have a name conflict, no?
<beach>
You should never :USE a package other than the CL package.
<beach>
... for that very reason.
* elderK
nods
<elderK>
That's good to know. I've been using package-local-nicknames, sometimes import-from.
<elderK>
Which do you use?
<beach>
Always package-local nicknames.
<beach>
With IMPORT-FROM you make it a bit harder for a person reading your code to guess where the symbols come from.
<elderK>
Can I assume that PLNs are pretty much everywhere at this point?
<elderK>
Kind of unrelated but does anyone care about GNU CL anymore? :D
<elderK>
I mean, it's not even ANSI, right?
<beach>
Correct, but they are everywhere.
<elderK>
Excellent!
<beach>
I don't know what problem package-inferred systems solve, but I know a lot of problems they introduce, so I never considered using them.
<elderK>
What kind of problems?
<elderK>
They definitely bring a lot of boilerplate if you aren't using uiop/define-package.
<beach>
It makes it a lot harder to use several files in a "module" that are part of the same package.
<beach>
And I still don't know what problem they are supposed to solve.
<metsomedog>
I tried making a Guix package for a system with package-inferred system, it was a nightmare
Ashy has left #commonlisp [WeeChat 3.6]
<elderK>
I wonder sometimes if they are popular because they are similar to what programmers from other languages are used to.
<elderK>
They are not the same as packages in C# or namespaces in C++ but they appear similar.
<elderK>
Even down to the x.y.z notation of package names.
<beach>
That might explain not only why some people like them, but also why I don't understand what problem they solve.
<elderK>
I read somewhere that package-inferred was good because it was "disciplined" and made it clearer where everything came from. Whether or not that's true, I have no idea.
<elderK>
I guess it could be useful if you wanted some functions that were only visible in a "single file." Say, some complex function that itself is implemented as lots of little parts, but you don't want anyone else to ever see those little parts.
gooba has quit [Remote host closed the connection]
gooba` has quit [Remote host closed the connection]
gooba has joined #commonlisp
wacki has joined #commonlisp
wacki has quit [Client Quit]
X-Scale has quit [Quit: Client closed]
Everything has quit [Ping timeout: 252 seconds]
treflip has joined #commonlisp
donleo has quit [Quit: Leaving]
triffid has quit [Remote host closed the connection]
triffid has joined #commonlisp
wacki has joined #commonlisp
jonatack has quit [Ping timeout: 248 seconds]
jonatack has joined #commonlisp
awlygj has quit [Ping timeout: 248 seconds]
treflip has quit [Remote host closed the connection]
treflip has joined #commonlisp
ym has joined #commonlisp
jon_atack has joined #commonlisp
jonatack has quit [Ping timeout: 260 seconds]
Everything has joined #commonlisp
younder has quit [Read error: Connection reset by peer]
younder has joined #commonlisp
NotThatRPG has joined #commonlisp
Gleefre has quit [Remote host closed the connection]
mgl has joined #commonlisp
metsomedog has quit [Quit: ERC 5.5.0.29.1 (IRC client for GNU Emacs 29.4)]
pranav has quit [Remote host closed the connection]
donleo has joined #commonlisp
oneeyedalien has joined #commonlisp
luna-is-here has joined #commonlisp
luna-is-here has quit [Client Quit]
attila_lendvai has joined #commonlisp
luna-is-here has joined #commonlisp
mishoo has joined #commonlisp
luna-is-here has quit [Client Quit]
oneeyedalien has quit [Ping timeout: 260 seconds]
Akbar-Birbal has left #commonlisp [#commonlisp]
cage has joined #commonlisp
cage has quit [Excess Flood]
cage has joined #commonlisp
mgl has quit [Ping timeout: 252 seconds]
kevingal has joined #commonlisp
pfdietz has quit [Quit: Client closed]
<aeth>
package-inferred-system solves the problem of very, very, very, very large projects
<aeth>
which is not a common problem in Common Lisp
<aeth>
It's probably not worth considering below 15,000 LoC, and CL is a concise language in terms of LoC, so it will be hard to get there.
<aeth>
It just adds inconvenience for the small projects that most CL projects are, but for larger ones, it means you can get away with only loading a part of it, which can save a lot of time.
<aeth>
It's probably not the ideal way to only load part of a large project because directory-level granularity is usually better than file-level granularity so for package-inferred-system you have to create a boilerplate use-reexport foo.lisp for every foo/ directory. But it's what ASDF offers.
<aeth>
It also means you have to define a bunch of extra packages for "internal" files that are only used elsewhere in that same directory, which use use, not use-reexport, in the foo.lisp package. If it was just directory-level, then you could avoid that.
younder has quit [Remote host closed the connection]
younder has joined #commonlisp
mgl has joined #commonlisp
pranav has joined #commonlisp
theruran has quit [Quit: Connection closed for inactivity]
Pixel_Outlaw has joined #commonlisp
cage has quit [Quit: rcirc on GNU Emacs 29.4]
varjag has joined #commonlisp
Everything has quit [Quit: leaving]
dra has joined #commonlisp
dra has quit [Changing host]
dra has joined #commonlisp
<paulapatience>
I don't really have a problem with large files, so I can get by without the boilerplate.
<paulapatience>
The main thing that I find annoying about package-inferred systems is that you cannot use the ~/ directive of FORMAT.
amb007 has quit [Ping timeout: 264 seconds]
treflip has quit [Ping timeout: 276 seconds]
mgl has quit [Ping timeout: 252 seconds]
amb007 has joined #commonlisp
Everything has joined #commonlisp
emaczen has joined #commonlisp
mishoo has quit [Ping timeout: 252 seconds]
pve has quit [Quit: leaving]
dustinm`_ has quit [Ping timeout: 252 seconds]
ym has quit [Ping timeout: 276 seconds]
spdegabrielle has joined #commonlisp
shka has quit [Quit: Konversation terminated!]
dustinm` has joined #commonlisp
Oladon1 has joined #commonlisp
Oladon has quit [Ping timeout: 252 seconds]
alcor has quit [Remote host closed the connection]
alcor has joined #commonlisp
mathrick has quit [Ping timeout: 252 seconds]
Everything has quit [Quit: leaving]
<aeth>
yes, that's a weird quirk in FORMAT, but I don't use that feature of it
amb007 has quit [Ping timeout: 260 seconds]
prokhor has quit [Ping timeout: 255 seconds]
prokhor has joined #commonlisp
wacki has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
donleo has quit [Ping timeout: 260 seconds]
dra has quit [Read error: Connection reset by peer]