<moon-child>
jcowan: as far as I know, the only languages that interface directly with c++ without compiling to it are d and raku. Are there any other notable ones?
* jcowan
shrugs
<jcowan>
I have no idea
yitzi has joined #commonlisp
waleee has quit [Ping timeout: 260 seconds]
doyougnu has quit [Remote host closed the connection]
<Guest85>
how do I call format such that it actually returns the formatted string
<Guest85>
rather than printing?
<Guest85>
(format nil "...~d..." 3) is not doing it
<ln43>
Hi all, i'm using Portacle on windows and quicklisp to load closer-mop but it does not seems to work since when i do closer-mop: and press tab there are not completions for the symbols exprted by that pachage
<ln43>
package... so, is there any possible solution, please?
<ln43>
yes i'm trying to reboot again sicl but the issue is that a symbol that should be required and it's defined inside that package is not available during the sicl boot
<ln43>
and quickloading closer-mop there is no error
<ln43>
but again, it seems like doesn't export symbols
srhm has quit [Read error: Connection reset by peer]
lottaquestions has joined #commonlisp
tyson2` has quit [Remote host closed the connection]
srhm has joined #commonlisp
<ln43>
ERROR while evaluating compile-time side effect:
<ln43>
The name "DIRECT-SLOT-DEFINITION" does not designate any package.
srhm has quit [Read error: Connection reset by peer]
<ln43>
mmh
<ln43>
anyway yes moon-child, i will try to delete the actual package and reinstall it but after inspection of the package's folder everythong seems ok... do you know if there is any other way to have closer-mop working ?
<ln43>
*everything
srhm has joined #commonlisp
Oladon has quit [Quit: Leaving.]
srhm has quit [Read error: Connection reset by peer]
srhm has joined #commonlisp
<ln43>
ok but i see sb-mop:direct-slot-definition, so why?
srhm has quit [Read error: Connection reset by peer]
dilated_dinosaur has quit [Ping timeout: 252 seconds]
srhm has joined #commonlisp
dilated_dinosaur has joined #commonlisp
_whitelogger has joined #commonlisp
<ln43>
ok thanks moon-child, after reinstallation seems like magically it works
keir has quit [Quit: keir]
d4ryus has quit [Ping timeout: 252 seconds]
ln43 has quit [Quit: Connection closed]
Guest92 has joined #commonlisp
<Guest92>
any april users?
<Guest92>
how can someone use a compiler macro so that it is not evaluated at compile time?
<moon-child>
Guest92: what are you trying to do?
<Guest92>
so (april:april-load ...) is a compile-time macro, I inserted it within a let block, but it is not evaluated when I call the function which houses the let block
<Guest92>
but it is reevaluated when I recompile
<Guest92>
this is super annoying
<Guest92>
as it means I can't just call the funciton, I have to compile it each time
<Guest92>
I suppose my own macro is in order which evaluates the other macro at runtime?
<Guest92>
Idk
d4ryus has joined #commonlisp
<moon-child>
ah, I see. A macro is very different from a compiler macro
<White_Flame>
in that case, the macro might be calling some other utility function which actually does the work. you should see if you could call that function instead
<White_Flame>
it's very handy for loader tools to work at compile-time, to capture any compilation errors right away as opposed to waiting for runtime, which is why it's written that way
<Guest92>
right, but this makes any sort of workflow absolutely monstrous
<Guest92>
I have to modify my apl file, switch to the lisp buffer, compile, switch to slime buffer, test the function
<Guest92>
its arduous
phantomics has joined #commonlisp
<saturn2>
you can use eval or macro-function to evaluate a macro at any time
gioyik has quit [Ping timeout: 276 seconds]
Oladon has joined #commonlisp
<Guest92>
(eval (april:april-load ...)))
<lotuseater>
ohai phantomics :)
char has quit [Ping timeout: 252 seconds]
<Guest92>
doesn't work
<phantomics>
hey lotuseater
<lotuseater>
oh noez
<Guest92>
phantomics hello
<Guest92>
I was just talking about you ;)
<saturn2>
Guest92: you need to quote the argument to eval
<phantomics>
Guest92: uh oh
<Guest92>
@saturn2 I see
<lotuseater>
saturn2: i thought if maybe a EVAL-WHEN could help (if really needed)
<Guest92>
phantomics I'm an apler, but trying to get the hang of working with april
<Guest92>
figuring out what my workflow should be
<saturn2>
lotuseater: well, the author(s) of april could use eval-when to make it work the way Guest92 expected
<phantomics>
Guest92 how's it going? Any questions?
<Guest92>
phantomics loads. Nested array model? or flat array model? or based array model? or...
<Guest92>
I can't seem to pass a list into april
<Guest92>
(april:april-c "myfn" '(some list))
<lotuseater>
cause a list is a list?
<moon-child>
Guest92: based, like cl
<Guest92>
right, but that could be ⊂"some" "list"
<phantomics>
They're based arrays in the sense that Marshall Lochbaum describes
<lotuseater>
it works on vectors, arrays, strings
<phantomics>
Because the arrays are native CL arrays
<phantomics>
April doesn't work on lists, it expects arrays
<Guest92>
ah
<Guest92>
I guess that makes sense now that you say it like that in the context of CL
<moon-child>
(my own implementation also uses that array model, which I didn't realise until I compared it to dyalog and dzaima and got strange results. I was somewhat gratified to find april behaved the same way!)
<phantomics>
However, you could have something that operates on lists if you pass the lists within an array and then use the :store-fn option to store a function within April that works on lists
<lotuseater>
Guest92: this gives you #0A#("some" "list") :)
<Guest92>
based does seem to be the "programmerly" mental model
<Guest92>
@phantomics is there a way to pass arguments to (april:april-load ...)
<Guest92>
though that's probably not what I want
<phantomics>
moon-child: in what places have you found April's arrays behaving differently from Dyalog?
<phantomics>
Guest92 let me see...
<Guest92>
Dyalog uses the nested model
<moon-child>
phantomics: one second, I will try to find it
<phantomics>
The underlying model is different but the behavior should be similar, since I automatically do some types of postprocessing to emulate Dyalog's behavior
<mfiano>
Where is AMOP's #'class-direct-methods defined? I don't see it defined in the book or in closer-mop.
<phantomics>
Guest92: you should be able to pass the same (with ...) parameters to (april-load) that you do to (april)
<moon-child>
hmm, that might be it. Perhaps I was using an older version? I seem to recall that ⍴0⌷(1 2)3 was ⍬ in dyalog, but ,2 in april
<moon-child>
but am no longer able to reproduce that
<phantomics>
Yes, in older versions there were inconsistencies in the array model
<phantomics>
I've made many changes in the last year, including those
<lotuseater>
phantomics: I was curious how you are the last days since we queried recently, so good you're back. :)
<moon-child>
~inconsistencies. Personally, I find the 'nested' approach less consistent. Especially for things like /
<phantomics>
Been busy with work and getting some last to-dos checked before a new April release
<phantomics>
Just today I got this working: 0 1 {o←⍤ ⋄ {o←⍥⋄1}⍣⍺⊢0 ⋄ 1 +o- ⍵}¨2
<phantomics>
Which I was told couldn't be done with a compiler
<moon-child>
(indeed, sometimes I think boxes may actually be ideal. If it was good enough for sharp...)
<moon-child>
phantomics: haha, nice
<lotuseater>
I thought so, you're very productive.
<lotuseater>
lel who told you so?
<moon-child>
phantomics: curious, do you also handle changing nameclasses?
<Guest92>
phantomics looks like there's some K in your APL?
<phantomics>
Guest92: yes, you can use K-style if-statements like $[1;2;3] -> 2
<lotuseater>
Guest92: easy easy :) one thing at a time
<phantomics>
Multiline defns are allowed
<phantomics>
But first-class functions are not yet
<Guest92>
but targeted to be supported?
<phantomics>
Maybe, or I may just try writing a BQN compiler since first-class functions are native to that lang and I could port all the April function impls over
<phantomics>
Scoping is the same as in Dyalog, when you assign a var inside a defn it's lexically scoped but you can do for example x←⊢1 to modify a variable outside a defn
<moon-child>
bqn has nice semantics but the syntax is :/
<Guest92>
Dyalog shadows each name, so basically each new assignment creates its own scope
<moon-child>
phantomics: you mean x∘←1?
<Guest92>
that's changed I believe in v18
<phantomics>
I mean x⊢←1
<lotuseater>
I should go to sleep, goodnight all. :)
<moon-child>
ah, that works too :)
<moon-child>
night lotus
<phantomics>
Night lotuseater, talk later
karlosz has quit [Quit: karlosz]
<lotuseater>
yes hopefully
<Guest92>
phantomics I guess what I meant by lexical scoping, are full clojures supported, because they are not in dyalgo
<hayley>
s/j/s/
karlosz has joined #commonlisp
<phantomics>
Guest92 what would an example be?
<lotuseater>
but okay I think when I'm awake again you're sleeping the next hours.
<phantomics>
One of the main differences to be aware of it that in user-defined operators, you use an underlined character like ⍹ to use the right operand as a value, and ⍵⍵ to use it as a function
<phantomics>
Handling the operands as either operands or functions is a real pain when compiling
<phantomics>
*either values or functions
<phantomics>
Since I'm not interpreting everything JIT
<moon-child>
that could handle changing nameclasses at runtime, w/o a hitch
kakuhen has joined #commonlisp
<phantomics>
btw moon-child what did you mean by changing nameclasses? Workspaces?
<moon-child>
no, name class. As in x←5⋄f←{x⍵}⋄x←+
<moon-child>
(name class is one of: noun verb adverb conjunction)
<phantomics>
Gotcha, that behavior is undefined, afaik it will work in some situations but break in others
<moon-child>
:/
<phantomics>
Nameclasses are handled by accounting of symbols in a lexer postprocessing stage that happens after the lexer converts characters to tokens but before those tokens are fed to the compiler
<Guest92>
so why april, and not a standalone? How "serious" is april? As in is it yet another APL toy or does it have a longer term agenda?
<phantomics>
But f←{x⍵}⋄x←+ should work without x←5
<beach>
Good morning everyone!
<phantomics>
Morning beach
<Guest92>
any larger applications dependant upon april?
<phantomics>
My goal is for April to be a professional-grade tool, not a toy. I'm using it in a hardware startup currently.
<Guest92>
wow
<phantomics>
April's biggest advantages are interoperability with CL and extensibility
<Guest92>
any emergent interop patterns yet revealed themeselves?
<phantomics>
You'll see the syntax for extending April's idiom with a new function, you can make a function or operator out of any Unicode symbol you like, as well as customizing the grammar patterns and utilities
<hayley>
I'm starting to think I need an APL implementation so I don't lose my mind in data science classes. So the best move would clearly be to use cl4py and April to embed APL in Python.
<moon-child>
haha
<phantomics>
As far as interop patterns, I'm often writing CL functions that wrap around an (april-c) call
<Guest92>
there's also the pynapl dyalog library
<Guest92>
hayley ↑↑
<phantomics>
There's a lot of depth to interop I have yet to explore via the :store-fn parameter
<Guest92>
phantomics so you're not using april-load much?
<hayley>
The other thing is that I need to write code in "Python", so downloading a language implementation manually is out of the question.
<phantomics>
Guest92: I use it sometimes for bigger pieces of code that merit their own file
<Guest92>
ah
<Guest92>
so what is your development cycle for such functions when april-load needs a recompile?
<Guest92>
(eval '(april-load...)) seems to do the trick, idk if I want that though
<lotuseater>
it can also be greatly seen and used as kind of a very powerful DSL to shorten code even more :)
<phantomics>
Often I'll just eval the (april-load) form with C-x C-e
<phantomics>
hayley: cl4py also calls an external Lisp so that wouldn't work either right?
<hayley>
phantomics: Yeah, unfortunately.
<phantomics>
I don't get why vector langs don't dominate in data science, they're vastly superior to any alternative for the field
<saturn2>
phantomics: you should probably make april-load expand to (eval-when (:compile-toplevel :execute) ...) rather than doing the work directly in the macro function
<hayley>
One fun example was counting the even numbers in an array. Should I write +/2|array or [x % 2 for x in array].count(0)? At least in Lisp we get COUNT-IF and EVENP.
<phantomics>
saturn2: thanks, I'll look into that
<moon-child>
cl doesn't even have many good tools for tacit programming. I think the only thing I'm regularly able to do point-free is :key #'c*r and similar. But no compose, hook, partially apply, ...
<hayley>
I'd also like a better relational algebra library too; Pandas seems to be picky about the order of operations sometimes. And apparently it gets too slow with mere thousands of rows.
<Guest92>
phantomics I don't understand why the concept of a general programming notation is not dominating computer science in general
<hayley>
Using Pandas makes me like SQL, which is really saying something.
<Guest92>
array programming languages tend to not be able to differentiate between the notation and notation on arrays
<moon-child>
actually lcompose/rcompose I don't think any language has except for j
<Guest92>
which to me is kind of annoying
<Guest92>
moon-childif you're talking about trains, BQN and APL have trains
<Guest92>
and I implemented functional trains in ngn/k
<phantomics>
One annoying shortcoming in APL is the inability to specify a matrix in code without really hackneyed syntax like x⍪←1 2 3 ⋄ x⍪←4 5 6
<Guest92>
moon-childI knw that's the dogma from the iversonian camp, but I think a generalized programming notation is the benefit of APL, not MERELY the arrays
<moon-child>
Guest92: I distinguish left compose from right compose. ((lcompose f g) x y) ←→ (f (g x) (g y)). Whereas ((rcompose f g) x y) ←→ (f (g x y))
<phantomics>
But with April you can specify the matrix in CL like #2A((1 2 3)(4 5 6)) and then pass it into April
<Guest92>
(f (g x y)) is just `f g x y` in APL
<Guest92>
and (f (g x) (g y)) is just `x ((g⊣) f (g⊢)) y ` in dyalog
<Guest92>
and bqn has that implicitly with ...
<Guest92>
g⊸f⟜g
<moon-child>
so, not as a first-class combinator, but something you have to implement yourself
<Guest92>
but there's also explicit "atop" in bqn so you can do f○
<Guest92>
g
<phantomics>
atop also exists in APL as ⍤
<Guest92>
in v18, yes
<phantomics>
And April
<moon-child>
obviously these are trivial to implement in any language with combinators. The question is, are those combinators primitive?
<Guest92>
in k
<Guest92>
I implemented forks, and atops just are normal k
<moon-child>
yes. Again, they can be trivially implemented in most languages. But they are not built in to most languages. That's all.
<Guest92>
avg:(+/;÷;
<Guest92>
avg:(+/;÷;≢:); (⍤⍳10) avg
<Guest92>
sorry for the typo :C
<Guest92>
moon-child I understand what you mean, Dyalog has many features of J because Roger Hui works for Dyalog now
<moon-child>
yes
Bike has quit [Quit: Lost terminal]
<lotuseater>
if they can pay him :)
<beach>
minion: memo for ln43: I think I introduced the problem you observed without noticing it, and then pushed the changes. So another pull would have fixed it.
<minion>
Remembered. I'll tell ln43 when he/she/it next speaks.
rain3 has joined #commonlisp
karlosz has quit [Quit: karlosz]
semz has quit [Ping timeout: 268 seconds]
defaultxr has joined #commonlisp
semz has joined #commonlisp
akoana has left #commonlisp [Leaving]
Oladon has quit [Quit: Leaving.]
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
hendursaga has quit [Ping timeout: 276 seconds]
lisp123 has joined #commonlisp
lisp123_ has joined #commonlisp
lisp123 has quit [Ping timeout: 265 seconds]
Inline has quit [Quit: Leaving]
pranavats has left #commonlisp [Disconnected: Replaced by new connection]
pranavats has joined #commonlisp
shka has joined #commonlisp
gaqwas has joined #commonlisp
<Guest92>
so I'm trying to define a package which depends on libraries and I want to then execute a primary function as a scrip
<Guest92>
anyone have a link to a demo or docs how I might do taht?
<Guest92>
i have an .asd file that has a :depends-on, and then I try to call a `sbcl --script file.lisp` that is mentioned in my .asd, but I don't think thats it
<beach>
I think you mean that you are trying to define a "system" rather than a "package", no?
<Guest92>
I dont actually know
<Guest92>
all I know is my script depends on a `ql:quickload`-ed library
<beach>
Systems are defined using ASDF whereas packages are defined using DEFPACKAGE.
<Guest92>
I want to execute the program programmatically
<White_Flame>
--script skips your .sbclrc init stuff, so quicklisp won't be loaded
<White_Flame>
you could do `sbcl --eval '(ql:quickload "my-thing")' `
<White_Flame>
or --load a small file which does a quickload & execution of your main entry
<White_Flame>
CL has a history as an OS, and thus plays much better with the repl than external launching, though you can generate full executables
<White_Flame>
the scripting environment hasn't taken off that much, though there are some utilities to help launch from various OS's cmdlines
<Guest92>
is that "mything.asd"?
<beach>
Yeah, I never start Common Lisp programs from the OS command line.
<Guest92>
:C
<Guest92>
but I need to execute the program under another programs control...
<White_Flame>
which 'that'?
Lycurgus has joined #commonlisp
<White_Flame>
oftentimes to accomplish that, you'll build an executable image from the lisp that the other program can launch. That avoids portability issues
<White_Flame>
(portability between different CL implementations, launching from different users, etc, not OS portability ofc)
gioyik has joined #commonlisp
<White_Flame>
or, you have the lisp running as a server, and it receives requests from other programs
<White_Flame>
but certainly you can make a little scripting solution that works for your exact use environment setup
<White_Flame>
*user environment setup
<White_Flame>
which would probably be sbcl --eval
<White_Flame>
or sbcl --load
<White_Flame>
or sbcl --script, if your .lisp script file does (load "~/.sbclrc") as its first thing
<White_Flame>
the various options affect if the debugger is launched, does it automatically exit, etc
<Guest92>
I don't have an sbclrc
<Guest92>
I have a .asd file
<White_Flame>
then how do you use quicklisp?
<White_Flame>
that's usually loaded via your .sbclrc
<Guest92>
um
<Guest92>
idk I set all that up ages ago
<White_Flame>
heh, well it's there, and it needs to be loaded for ql to function
<White_Flame>
does quickloading your .asd system from the repl work normally?
<White_Flame>
either it needs to be symlinked from ~/quicklisp/local-projects/, or added to your asdf:*central-registry* to be visible by default
<Guest92>
ah, so defpackage, then in-package, then the code I need with a (cl-user::exit) at the end does what I need
<Guest92>
its kind of a lot to just run a program
nature has quit [Ping timeout: 260 seconds]
<Guest92>
`sbcl --load file.lisp` is the ticket
<Guest92>
with (cl-user::exit)
<Guest92>
but holy cow that is really a lot of stuff
<rain3>
just sbcl --load file.lisp and put the code in it and that should do
<saturn2>
you can also use sbcl as a script interpreter
<saturn2>
with a shebang line
amb007 has quit [Ping timeout: 265 seconds]
amb007 has joined #commonlisp
vats has joined #commonlisp
makomo_ has quit [Ping timeout: 268 seconds]
selwyn has joined #commonlisp
pve has joined #commonlisp
srhm has quit [Read error: Connection reset by peer]
srhm has joined #commonlisp
cosimone has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
gaqwas has quit [Ping timeout: 265 seconds]
Lycurgus has quit [Quit: Exeunt]
srhm has quit [Quit: Konversation terminated!]
srhm has joined #commonlisp
gioyik has quit [Quit: WeeChat 3.1]
_Posterdati_ has joined #commonlisp
Posterdati has quit [Ping timeout: 245 seconds]
elderK has quit [Quit: Connection closed for inactivity]
heisig has joined #commonlisp
lottaquestions_ has joined #commonlisp
lottaquestions has quit [Ping timeout: 260 seconds]
scymtym has quit [Remote host closed the connection]
makomo_ has joined #commonlisp
heisig has quit [Remote host closed the connection]
heisig has joined #commonlisp
rgherdt has joined #commonlisp
notzmv has quit [Ping timeout: 260 seconds]
vats has quit [Ping timeout: 265 seconds]
makomo_ has quit [Quit: WeeChat 3.2]
attila_lendvai has joined #commonlisp
selwyn has quit [Read error: Connection reset by peer]
scymtym has joined #commonlisp
srhm has quit [Read error: Connection reset by peer]
srhm has joined #commonlisp
<lisp123_>
What new concepts are taught in AMOP that are not an application of Macros or other basic programming concepts?
<loke[m]>
lisp123_: object orientation.
<lisp123_>
Could you expand on that?
<lisp123_>
Is it in terms of redefining the rules of CLOS?
<rudi>
programmable objects
<rudi>
an API to redefine rules of CLOS, yes
<rudi>
but in the end, it's all macros and basic programming concepts ... I don't know what to tell you except to look at the table of contents and introduction chapter :)
<lisp123_>
Because (from my very rudimentary understanding), objects can be represented by closures - so I get that CLOS etc. are well refined object oriented systems, but is there any new programming concepts in AMOP? I only say this because eveyrbody says its one of the best books in CL, I have a copy but haven't started reading
<ecraven>
there are valuable concepts that are more complex than closures...
<lisp123_>
I read the foreword / introduction chapter
<loke[m]>
Possibly, but I don't understand the question. AMOP is about topics which are absolutely not just functions and macros. It's about object orientation, and a specific implementation of it based on generic functions.
<ecraven>
this is the same as saying "I understand assembly language, does any other language add anything useful beyond that"? and the answer is (for probably any language): yes, there are valuable new things to be learned ;)
<lisp123_>
ecraven: Fair enough :D
<ecraven>
CLOS offers a very interesting model of extending object orientation in various directions. for example, generic functions are a very useful concept (which is not very widespread outside of a few specific languages)
<loke[m]>
ecraven: Unless the language is Python. Then no.
<lisp123_>
loke[m]: Okay, so basically there's a lot more to object orientation, which I seem to be missing, hence I don't fully get why its not "more advanced" version of the basic concepts I've learnt so far
<ecraven>
loke[m]: fortunately, I haven't had to deal with python in detail, I haven't seen anything I didn't see in other languages too
<lisp123_>
Perhaps thats the missing link in my understanding
<ecraven>
Lisp, APL, Forth, Prolog, that's the type of language that I'm thinking about ;)
<ecraven>
well, what *have* you learned so far?
<lisp123_>
Well I equated OO to closures for the most part
waleee has joined #commonlisp
<ecraven>
closures might be an implementation technique for OO, but the concepts are unrelated to closures
<loke[m]>
lisp123_: That would be more akin to structures
<loke[m]>
`struct` in C is basically a container of values, which can be emulated uing a closure.
<loke[m]>
s/uing/using/
<lisp123_>
Hmmm ok
<lisp123_>
loke[m]: Yes that's right
<loke[m]>
In fact, in CLOS, the ability to arrange members (called slots) in classes is probably the least interesting aspect of it.
<loke[m]>
People should probably learn CLOS by using generic functions and the standard datatypes. and look at defclass later.
<lisp123_>
I naively viewed generic functions as a massive COND table
<lisp123_>
What stood out to me in the intro of AMOP was this - "Rather than supplying the user with a fixed, single point in the space of all language designs and implementations, we would instead support a region of possible designs within that overall space"
<lisp123_>
So I figured the status of the book as one of the very best in CL came from that, and hence the original question
<loke[m]>
lisp123_: I'm currently implementing some code in Kotlin which does not have generic functions, and trust me, the when-tables I have to create for every single function is ridiculous. While it's certainly possible to replicate the behaviour using essentially if-statements everywhere, it's similar to arguing that you don't need support for floating point numbers because you can just use NAND.
<lisp123_>
Like the above sentence to me sounds more than just a very good book on OO, but rather something even more fundamental to all of computer science
<rudi>
it describes ways of subclassing classes, slots, generic functions, etc., and implement different behaviors when you use such a class, call such a function, etc.
<rudi>
hence the "meta" in its title - it's programming your OO system to do stuff
<lisp123_>
I see
<lisp123_>
So looks my takeaways are - OO is a much important concept than just its surface level definitions and (b) taking an OO approach to writing programs in the sense of 'Metaobjects' is profoundly better than the basic approach we get taught first in terms of everything is just building upon procedures and functions
<_death>
lisp123_: it is about introducing points of extension for the user (application programmer) so that a variety of decisions can be made.. it is done in a principled way to allow for efficiency and consistency in the face of different extensions.. the usual choice would've been to disallow extension (closed systems)
<lisp123_>
_death: Thanks for that. Do you have examples of extensions? Is that something like evaluation order (e..g for functions evaluate all arguments before the function)
yitzi has quit [Remote host closed the connection]
yitzi has joined #commonlisp
<rudi>
lisp123_: is this for homework?
yitzi has quit [Client Quit]
<loke[m]>
lisp123_: Why don't you just read the book?
<_death>
lisp123_: the AMOP book has examples.. for example it's easy to write an object browser (an example of MOP giving means of introspection) or a system allowing persistent instances.. being able to change the evaluation order is also a good example, if you apply MOP principles to your evaluator (the Paepcke book I mentioned has a paper about this)
<lisp123_>
_death: Thanks for that, very useful
<beach>
I think everyone missed the totally essential part of the AMOP namely that it implements CLOS using CLOS.
<beach>
Or, even more "meta", it defines the behavior of CLOS using a CLOS program.
<lisp123_>
That seems very cool
<beach>
This aspect is what makes Common Lisp bootstrapping interesting, to me at least. It means that the best way to describe how Common Lisp works is that it is the result of executing Common Lisp code. And then the best way of implementing Common Lisp is by extension actually executing some Common Lisp code. Which is exactly how we do it in SICL bootstrapping.
<lisp123_>
That sort of sounds like an advanced (compound?) version of how lisp is said to be/have a meta circular evaluator?
<_death>
it's another turtle in the chain :)
<beach>
Yes, but the typical metacircular evaluator is only concerned with ordinary functions, and it doesn't handle classes.
<lisp123_>
(if lisp allows for primitives to be evaluated meta circurlarly, then MOP/CLOS is for compound objects)
<lisp123_>
Okay, that's pretty cool and I guess what I was after in terms of what's special about AMOP
<beach>
I wouldn't say that. As many pointed out, generic dispatch is very useful for built-in classes as well, like numbers.
selwyn has joined #commonlisp
<lisp123_>
Understood
<beach>
Now, at the end of the book, and also in their PCL implementation, they tweak the otherwise metacircular code to make it operational. As it turns out, it is already operational, provided you execute it in a host Common Lisp system with an existing CLOS implementation. Which is what we do in SICL bootstrapping.
kakuhen has quit [Quit: Leaving...]
<lisp123_>
Nice, I will keep an eye out for that when I get to that
<beach>
So we can evaluate forms like (defclass t () () (:metaclass built-in-class)) and (defclass standard-class (...) ...)
<lisp123_>
Within an existing CLOS implementation right?
<lisp123_>
So you define your own SICL implementation, and then run it within an existing CLOS implementation?
<beach>
In the first stage of bootstrapping, yes. But then it executes itself.
<beach>
No, not at all.
<beach>
I mean, we do during bootstrapping, but the result is a new system.
<lisp123_>
And afterwards, somebody else can create their own implementation by redefining CLOS in your SICL implementation?
<beach>
I am not sure what that means.
<beach>
Someone else can just do what I did and they will have their own CLOS implementation.
<_death>
AMOP taught me that (most of) CLOS is simple and elegant, even if production-quality implementations and some corners are hairy
heisig has quit [Remote host closed the connection]
<beach>
As I wrote in one of my papers, the entire chapter "Living with circularity" is not necessary.
heisig has joined #commonlisp
<beach>
_death: Sure, but most warts are due to their assumption that CLOS is going to be added to a pre-ANSI Common Lisp implementation. We fixed those warts.
<_death>
beach: that's great.. I've yet to read the CLOS implementation in SICL
<beach>
That won't teach you much, as my (defclass t... example shows. The tough part is bootstrapping.
<lisp123_>
beach: I figured it would be somehow "better" to bootstrap from SICL than from another implementation, even if they could just simply repeat what you did
<beach>
lisp123_: Possibly, since we have first-class global environments.
heisig has quit [Remote host closed the connection]
frgo has quit [Remote host closed the connection]
heisig has joined #commonlisp
<beach>
_death: Well, there is also stuff like generic dispatch, which is an implementation detail, but an important one for performance.
frgo has joined #commonlisp
<lisp123_>
Okay, so my conclusion are as follows. (1) Book on Algorithms -> Teaches basic, primitive ideas of how to code directly with hardware & how to write efficient code. (2) SICP -> Teaches the value of abstraction and building compound objects / higher order functions etc. (and various discussions on that), AMOP -> Teaches the value of organising software / implementations in an 'object' style and the various considerations for that (i.e. for l
<lisp123_>
arge projects, this organisational advantage of OO code should not be discounted and regarded just as a set of procedures / macros over the basic primitives)e value of organising software / implementations in an 'object' style and the various considerations for that (i.e. for large projects, this organisational advantage of OO code should not be discounted and regard
random-nick has joined #commonlisp
<lisp123_>
(sorry some text accidentally got copied twice in the above)
<_death>
beach: right, some of the hair in production-quality implementations is due to making things efficient
<lisp123_>
( rudi & loke[m] - no not for homework, just wanted to have a quick summary in my head as I went about reading things. I will hopefully get to reading AMOP soon, saving it for a nice holiday)
<_death>
beach: I meant that, e.g., Closette was a simple program and it shows a simplified CLOS.. other treatments implementing CLOS-like object systems are too far away from it
<beach>
Yes, I see.
* beach
vanishes to fix lunch for his favorite coauthor.
<mfiano>
lisp123_: Object orientation covers more ground in CLOS than class-centric OO languages. Generic functions, which are represented by class metaobjects, form the primary way of [re]defining behavior, and this system is integrated into the core of the language. AMOP is a nice book for all of the reasons already mentioned. It is however, a technical book, and the writing style and number of errors
<mfiano>
is not very good. The content though is excellent.
<lisp123_>
mfiano: Thanks for that. Yes, it was a bit hard to read so I put it off for just now. It does seem like I need to have more appreciation for generic functions than I have thus far, so that's one of my takeways
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
<mfiano>
I didn't have an appreciation for generic functions or the rest of CLOS until I actually started working on my own projects.
heisig has quit [Remote host closed the connection]
heisig has joined #commonlisp
<mfiano>
Playing around with generic functions to see how they work, even if it's just using the "on-stage" (AMOP metaphor) interface, and then integrating them into a real project, is also eye-opening.
<lisp123_>
I had some experience when I was writing some card games in Swift (for example a generic sort function which then is specialised on which type of cards one is using or what are the rules of the particular game) - that was definitely a great experience for me
<lisp123_>
I moved away from CLOS recently, but now I think that was just because I designed the objects badly
<lisp123_>
So I will revisit
<mfiano>
I am not familiar with that language, but generic functions in CL, even without getting into meta-stuff, is very flexible, with auxiliary methods, method-combination, etc
<lisp123_>
One thing that tripped me up with axuiliary methods was that they didn't have access to lexical scope
<lisp123_>
within the main method or other auxiliary methods -> but now that I have learnt macros, I can implement that myself
<mfiano>
Well, :around methods are for when you need to replace the primary method, which can optionally call out to the primary method, so you can lexically bind it's result and refer to it
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
<mfiano>
You can also call the next applicable method from primary methods
notzmv has joined #commonlisp
cosimone` has joined #commonlisp
<lisp123_>
I struggled with :around, I will have a look at that again - thanks!
<mfiano>
Well unlike :before and :after that runs before or after the primary method, an around method _replaces_ the primary method...the return value of the around method is used.
<mfiano>
But, you can still call what would have been the original primary method
heisig has quit [Quit: Leaving]
<mfiano>
The optional calling is done with #'call-next-method
cosimone has quit [Ping timeout: 268 seconds]
<mfiano>
This is a very powerful concept for extending new behaviors
<Shinmera>
? it doesn't replace the primary method. It goes around all of the other methods, including :befores and :afters
<mfiano>
I guess that was worded poorly. I was referring to this official passage: "An around method specifies code that is to be run instead of other applicable methods, but which might contain explicit code which calls some of those shadowed methods (via call-next-method)."
<lisp123_>
Thanks! I will play around with #'call-next-method now
<rain3>
https://lispcookbook.github.io/cl-cookbook/clos.html "Think of it as an onion, with all the :around methods in the outermost layer, :before and :after methods in the middle layer, and primary methods on the inside."
<hayley>
"Method combinations are like ogres."
<antoszka>
lol
<lisp123_>
Thanks Shinmera & rain3, very useful
<lotuseater>
haha I definitely know where this is coming from :D
attila_lendvai has quit [Ping timeout: 268 seconds]
hendursaga has joined #commonlisp
Everything has joined #commonlisp
heisig has joined #commonlisp
heisig has quit [Client Quit]
vats has joined #commonlisp
vats has quit [Ping timeout: 240 seconds]
vats has joined #commonlisp
tyson2 has joined #commonlisp
<lisp123_>
I am having issues copying a vector which has a fill pointer, and then doing vector-push-extend on the new vector
<lisp123_>
Any tips?
<lotuseater>
so it's also an adjustable vector?
<lisp123_>
yes
<lotuseater>
did you use COPY-SEQ ? I have to try out
<lisp123_>
I did
<lotuseater>
so hmm what does clhs say about it?
<lisp123_>
Looks like I may need to manually copy and not use copy-seq
yitzi has joined #commonlisp
<lisp123_>
If sequence is a vector, the result is a fresh simple array of rank one that has the same actual array element type as sequence.
<lotuseater>
yes I was about to paste it ^^
vats has quit [Ping timeout: 260 seconds]
<lisp123_>
looks like the :adjustable property doesn't get copied across, but I don't see particular mention of that above?
<lisp123_>
Is that the "rank 1" bit?
<lisp123_>
ah the "simply array"
<lotuseater>
so write yourself a COPY-VECTOR or so which checks if it has fill-pointer and/or is adjustable
<lisp123_>
thanks
<lotuseater>
like you want and need it :)
<lisp123_>
:)
Duuqnd has joined #commonlisp
cosimone` has quit [Ping timeout: 268 seconds]
X-Scale` has joined #commonlisp
<lotuseater>
and also with just a fill-pointer it's not a simple-vector indeed
X-Scale has quit [Ping timeout: 268 seconds]
X-Scale` is now known as X-Scale
<lisp123_>
I see
<lisp123_>
I created my first vector today :)
<lisp123_>
#efficient-programming #nomorelists
<lotuseater>
yesterday I asked something in #clojure and the discussion went to that someone said "pattern matching 100% doesn't belong in a library, it's a 'fundamental' feature" ○_∘
<jackdaniel>
same goes for parsing json, essential language feature
<jackdaniel>
and mp3, I forgot about mp3
<lotuseater>
right right
<lotuseater>
with sentences like that someone shows well how less things are really understood
<jackdaniel>
it is not that wiring a functionality in a library make its users comprehend the topic more compared to a built in feature
<lotuseater>
lisp123_: please don't assume lists as inefficient
<hayley>
I really don't like non-extensible pattern matchers, which so happen to usually be inbuilt pattern matchers.
<lisp123_>
lotuseater: No, of course not :) Just in the right places, vectors are better
<lotuseater>
yes just because something *looks* like "built-in" whereelse cause you're locked out from the beginning doesn't mean it really is
<lotuseater>
lisp123_: i know
<hayley>
To a zeroth approximation, a modular pattern matcher would let you provide any accessor functions to destructure an object.
<lotuseater>
yeah having that in the macro which turns it on is even nicer too :)
<hayley>
Of course, Clojure programmers shy at encapsulation and the use of data structures which aren't persistent vectors and maps, so it is a non-issue for them.
<lotuseater>
and even more, it's a thing you don't want to have in a real language spec, cause there are too much possibilities and variations, like with regular expressions in general
<hayley>
Once I wrote that pattern matching and hash tables seemed like old ideas, but for which people can't stop inventing new implementations of. So I wouldn't want to maintain a pattern matcher really.
<jackdaniel>
I doubt that this would make a strong point when comparing clojure with commonlisp (which has quite a few "wired" behaviors, most notably for sequences)
<jackdaniel>
maybe not "most notably", but "for example"
<hayley>
.oO(Everything I don't like is anti-modular: the hayley's guide to language features)
<jackdaniel>
you can't loop operators, map operators etc etc
<jackdaniel>
s/can't/can't extend/
<rain3>
Shinmera: I'd like to port https://github.com/rainthree/manardb to windows , this mmap layer is almost fine: https://github.com/Shinmera/mmap/blob/master/windows.lisp#L222 but its api accepts only pathnames , not file descriptors, while the code that has to be ported calls open-file then mmap on the descriptor . Do you allow me to clone your code and modify it as I want , or would you prefer me to fork then submit pull
<rain3>
requests? (in this case I will have to bother you about changes and you may not agree to the changes I want to make and we will waste time)
<Shinmera>
rain3: It seems like it would be simpler to me to change the code you're porting to just use the mmap library instead of open-file and mmap separately.
<rain3>
maybe, but would that be correct ? to make it work with a 'too' high-level api?
<Shinmera>
why would it be "too high level"
<Shinmera>
The mmap api does return the fd (kinda) in its second argument, so if you absolutely need it for something you can get it from there, too.
<Shinmera>
err, second return value
<rain3>
ok I will give it a try
<mfiano>
lisp123_: alexandria:copy-array
<lotuseater>
mfiano: so the copy-vector could be left for them as an exercise :)
<mfiano>
Hmm?
<lotuseater>
hmm?
<mfiano>
I don't understand your comment. A vector is an array
<lotuseater>
so that lisp123_ works through it but also is aware of a general function in a lirary which does it
<lotuseater>
of course
<mfiano>
I see
john-a-carroll has joined #commonlisp
jeosol has quit [Ping timeout: 252 seconds]
<lotuseater>
lisp123_: chapter 5 in Common Lisp recipes could also be good for you now
john-a-carroll has quit [Quit: Ping timeout (120 seconds)]
<lisp123_>
lotuseater: Thanks for the tip, will check it out
<lisp123_>
mfiano: Thanks, I'm trying to avoid alexandria as much as possible (minimise code dependency surface)
<rain3>
Shinmera: by "too high level" I meant that it does two things (1. opening a file , 2. mmapping it) , so in the original code to accommodate to that, at this line for example https://github.com/rainthree/manardb/blob/5d8fc843057b70e831ca1bfc4912ae2b24ab73d4/src/mtagmap.lisp#L168 I will have to do an extra remap (or munmap + mmap for systems that don't have remap) . It can be done, but another way would be to make a separate
<rain3>
layer library (in which I may steal/inspire few lines from yours) that also has open-file exposed in the public api, along with other apis (that don't have anything to do with mmap)
<lotuseater>
you shouldn't do so
<rain3>
*an extra remap before truncating the file because it will be already mmapped and truncate won't work before first remapping with the new length
<Shinmera>
rain3: It must do two things in order to stay properly portable across systems. The semantics of opening a file and mapping are quite different on windows vs unix.
<Shinmera>
I don't much see the point of exposing the fd myself.
<Shinmera>
There isn't really anything to do with it once things have been mapped.
cage has joined #commonlisp
didi has joined #commonlisp
<didi>
Should GETHASH be faster for hash tables with test EQL than EQUAL?
<hayley>
Well, for the key objects for which EQUAL and EQL hash tables are equivalent, EQUAL conceptually calls EQL. So EQL might be faster?
Bike has joined #commonlisp
<didi>
So let's go a step further: Should GETHASH be faster for hash tables with test EQL and testing integers than with test EQUAL and testing strings?
<hayley>
Now it depends on if EQ would work; are the integers fixnums and are EQUAL string keys EQ (possibly by some other interning)?
<didi>
hayley: oic. Lots of IFs. Thank you.
<hayley>
If one is true but the other isn't, the true one will be faster. If both are true, they're probably the same. If neither is true, no one knows.
<didi>
Thank you, hayley.
<hayley>
Sure.
cosimone has joined #commonlisp
<fitzsim>
stylewarning: I'm working through intro-to-coalton.md
<fitzsim>
I think the do-notation example has a typo in the result comment
<fitzsim>
but in trying to prove it, I'm not how to print the resulting list
<fitzsim>
I'm not sure how to resolve the value there (or just print it as 4+3)
tyson2 has quit [Quit: ERC (IRC client for Emacs 27.2)]
cosimone has quit [Ping timeout: 268 seconds]
tyson2 has joined #commonlisp
char has joined #commonlisp
Devon has quit [Ping timeout: 268 seconds]
seok has quit [Ping timeout: 252 seconds]
mariari has quit [Quit: WeeChat 3.2]
mariari has joined #commonlisp
Duuqnd has quit [Ping timeout: 268 seconds]
doyougnu has joined #commonlisp
molson_ has joined #commonlisp
molson has quit [Ping timeout: 268 seconds]
Devon has joined #commonlisp
Devon has quit [Ping timeout: 260 seconds]
cranium has joined #commonlisp
<pjb>
didi: the difference implied by the test is foremost a difference of hash function.
<pjb>
didi: basically a eql hash-table will use as hash value either the address of the object, or (if a moving gc is used), a unique ID.
<pjb>
didi: while with an equal hash-table, for objects where that makes a difference, the hash-function will have to process the object value (eg. make an sum of some of the hash of the slots in a vector or list).
<didi>
pjb: oic. So I'm guessing there will be a difference in performance.
<pjb>
didi: but this is what lets you use them as key, so you do want this difference!
<pjb>
eg. if your keys are numbers, then equal uses eql which tests if the numbers are of same type and = ; but if your keys are string then equal uses (every 'equal str1 str2) to test each character. O(n)… Sometimes you may want to use a hash-table :test eql with strings, but in general you don't, you want the :test equal.
<pjb>
so the question of performance is irrelevant!
<didi>
oic Thanks.
<doyougnu>
Hi all, does anyone have a reference or link to get started on NixOS? I'm getting errors when looking for foreign libs like libssl.so
<dualinverter[m]>
What are you trying to do? doyougnu
jeosol has joined #commonlisp
<doyougnu>
dualinverter[m]: trying to install hutchentoot.
cosimone has joined #commonlisp
contrapunctus has left #commonlisp [#commonlisp]
<doyougnu>
I was just seeing if there was anyone else in here that used NixOS. I found some NixOS related posts about it, looks like PACKAGE_CONFIG_PATH needs to refer to where nixos stores binaries
<etimmons>
doyougnu: Doesn't actually answer your question, but if you don't really need SSL support in hunchentoot you can push :hunchentoot-no-ssl to *features* before loading it
<doyougnu>
dualinverter[m]: thanks for the input. I'll toy around with some derivations. I suspect i'll have to wrap SLIME in a nix-shell to get it working.
yitzi has quit [Quit: Leaving]
nature has joined #commonlisp
_Posterdati_ has quit [Ping timeout: 268 seconds]
_Posterdati_ has joined #commonlisp
_Posterdati_ has quit [Excess Flood]
contrapunctus has joined #commonlisp
tyson2 has quit [Quit: ERC (IRC client for Emacs 27.2)]
_Posterdati_ has joined #commonlisp
eddof13 has joined #commonlisp
selwyn has quit [Read error: Connection reset by peer]
cranium has quit [Quit: Leaving]
yitzi has joined #commonlisp
tyson2 has joined #commonlisp
amb007 has quit [Ping timeout: 252 seconds]
amb007 has joined #commonlisp
vats has joined #commonlisp
Lycurgus has joined #commonlisp
lisp123_ has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
random-nick has quit [Quit: quit]
lisp123 has quit [Ping timeout: 260 seconds]
trriplex has joined #commonlisp
random-nick has joined #commonlisp
srhm has quit [Read error: Connection reset by peer]
srhm has joined #commonlisp
ec_ has joined #commonlisp
Lycurgus has quit [Quit: Exeunt]
trriplex has quit [Ping timeout: 252 seconds]
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
lisp123 has joined #commonlisp
<akater[m]>
Should (map-into #(0 0 0) #'identity) error? SBCL errors here due to invalid number of arguments but it does not error e.g. on (map-into #(0 0 0) #'identity nil nil).
amb007 has quit [Read error: Connection reset by peer]
<Bike>
identity takes the wrong number of arguments, so it's undefined behavior, i think
<_death>
you shouldn't pass a literal there
<mfiano>
result sequence shouldnt be a literal
lisp123 has quit [Ping timeout: 265 seconds]
ahlk has quit [Remote host closed the connection]
amb007 has joined #commonlisp
<scymtym>
(map-into … … nil nil) does not call the function. (map-into (vector 1 2 3) #'identity '(1) '(2)) signals an error due to wrong number of arguments
amb007 has quit [Read error: Connection reset by peer]
<mfiano>
identity takes 1 argument, so should be given 1 sequence
<scymtym>
but i don't think the compiler is supposed to figure that out without calling the function
<didi>
If one follows the backtrace, it evals `(apply really-fun args)' inside `map-into'.
ec_ has quit [Ping timeout: 276 seconds]
lisp123 has joined #commonlisp
<akater[m]>
didi: See the example above.
eddof13 has joined #commonlisp
<akater[m]>
Elements are set to successive values of (funcall f). That's what should indeed happen.
<didi>
akater[m]: #'f doesn't accept arguments; #'identity does. The surprise, for me, is that `map-into' applies the function even if there is not sequence.
<didi>
s/not/no
ec_ has joined #commonlisp
eddof13 has quit [Client Quit]
eddof13 has joined #commonlisp
<didi>
It makes sense, tho.
<pjb>
counting starts at 0.
<pjb>
akater[m]: there's no point in naming a function with f !!! Use lambda: (map-into (make-list 3) (lambda () (random 3))) #| --> (2 2 2) |#