Xach changed the topic of #commonlisp to: Common Lisp, the #1=(programmable . #1#) programming language | Wiki: <https://www.cliki.net> | IRC Logs: <https://irclog.tymoon.eu/libera/%23commonlisp> | Cookbook: <https://lispcookbook.github.io/cl-cookbook>
Fare has joined #commonlisp
tyson2 has joined #commonlisp
random-nick has quit [Ping timeout: 258 seconds]
Spawns_Carpeting has joined #commonlisp
<Spawns_Carpeting> Is anyone here familar with SBCL and the --script command line flag?
lisp123 has joined #commonlisp
lisp123 has quit [Ping timeout: 258 seconds]
makomo has quit [Ping timeout: 258 seconds]
Bike has joined #commonlisp
<Josh_2> What bout it?
dsk has joined #commonlisp
akoana has left #commonlisp [#commonlisp]
<hayley> It is like --load, but SBCL quits immediately after and the debugger is disabled, from memory.
<lotuseater> so it says to the debugger "you have no power here!" :D
lisp123 has joined #commonlisp
nij- has quit [Ping timeout: 272 seconds]
<White_Flame> it also ignores your .sbclrc
lisp123 has quit [Read error: Connection reset by peer]
Spawns_Carpeting has quit [Quit: ZNC 1.7.2+deb3 - https://znc.in]
Spawns_Carpeting has joined #commonlisp
<kakuhen> When I have a funcallable-standard-object, the function of the object is called the "instance function," right?
<kakuhen> I'm guessing this based off the name set-funcallable-instance-function
waleee has quit [Ping timeout: 256 seconds]
<Bike> Probably yes, but what is the context?
<kakuhen> im writing documentation for some of my code
<kakuhen> I have a funcallable-standard-object with two slots, one of which hosts a function, and I want a precise word that tells the reader I mean the function of the instance, not the function in that one slot.
<kakuhen> funcallable-standard-class* sry
<Bike> ah. in that case "instance function" should do, sure.
<kakuhen> sweet thanks
kuler has joined #commonlisp
kuler has quit [Remote host closed the connection]
kuler has joined #commonlisp
White_Flame has quit [Remote host closed the connection]
White_Flame has joined #commonlisp
prxq has joined #commonlisp
prxq_ has quit [Ping timeout: 268 seconds]
tyson2 has quit [Remote host closed the connection]
taiju has quit [Ping timeout: 272 seconds]
<beach> Good morning everyone!
<lotuseater> Good morning beach :)
Josh_2 has quit [Ping timeout: 248 seconds]
<loke[m]> <nij-> "maxima-client seems to be..." <- Maxima can load using asdf.
<loke[m]> And Climaxima works fine, even though it's not "complete".
<loke[m]> Things like wxmaxima runs Maxima in a separate process and communicates with it using a separate protocol. Climaxima doesn't do that. It's all Lisp in a single process.
<beach> Hey loke[m]. I was about to recommend that nij- talk to you about Maxima.
<loke[m]> beach I actually just woke up, I saw the notification on my phone.
<beach> Heh, OK.
<beach> Did you party last night?
<beach> I guess you could be on vacation in some remote Scandinavian country or so.
<Qwnavery> (cdr '(defvar *test* "test"))
<Qwnavery> It's absurd.
<loke[m]> The readme should probably be improved. A lot of the difficulty in building's comedy from the step that converts the documentation to sexps. It needs to run all the examples in the code so that the results can be recorded in the internal format. But if you're OK with not having the documentation then that step can be skipped.
<lotuseater> Sweden or Norway must be beautiful. A friend of mine is travelling now with a camper there.
<lotuseater> Qwnavery: why?
<Qwnavery> lotuseater: Because every other language lacks it.
<Qwnavery> It's a good kind of absurd.
<loke[m]> beach no. It's weekend so I usually sleep till noon. 😃
<Qwnavery> It makes sense.
<beach> Qwnavery: "it"?
<beach> loke[m]: Good for you!
<lotuseater> yes what exactly do you mean?
<Qwnavery> I get it. You can write code that writes code because you can treat code as lists.
<lotuseater> and there are also other languages that are kind of homoiconic
<beach> Qwnavery: What is "absurd" is that people still program in languages that are *not* homoiconic.
<Qwnavery> beach: exactly.
CrashTestDummy3 has joined #commonlisp
<Qwnavery> lotuseater: I sorta got it yesterday, it just sunk in like 2 minutes ago.
<Qwnavery> (macroexpand (my-brain))
<lotuseater> good so our efforts are a good investement
<beach> Qwnavery: As I often say, people spend a lot of energy and time to avoid learning Common Lisp.
<Qwnavery> beach: but why?
<Qwnavery> It's liberating.
CrashTestDummy2 has quit [Ping timeout: 268 seconds]
<Qwnavery> also, beach I'd like to apologize for my arrogance about mentoring the other day. lotuseater taught me some fundamentals, I wouldn't have realized how neccessary mentorship is without him.
<beach> Qwnavery: There are several explanations, but mostly because it is not taught in teaching programs, and when people finally discover it, they have already invested a lot of effort into something sub-optimial, so then it becomes hard to admit the situation.
<lotuseater> Qwnavery: So today you can spend thinking of why PUSH is a macro but VECTOR-PUSH is not.
<hayley> I may have a theory, but I only really joined the pieces up yesterday. It is sure liberating, but it seems in some environments that you are treated like a moron who can't think for themselves, despite being hired to be good at programming and design.
* lotuseater hides away
<beach> Qwnavery: Sure, no problem. Good luck with further learning.
<beach> hayley: How is that observation related to not learning Common Lisp?
<hayley> beach: Right. People then say that Lisp is impractical because of this flexibility, so other people decide to not learn Lisp.
<beach> hayley: I still don't understand whether the person being treated like a moron is the one that might want to learn Common Lisp, or the one that then absolutely won't.
<lotuseater> Or they like more to believe such phrases "Learn full Java in 24 hours".
<hayley> Okay, I don't understand what I just said.
<hayley> Just a moment...
<beach> No wonder *I* didn't then.
<hayley> Sorry.
<lotuseater> beach: How do you deal/argue with people who say "Nobody needs that." like one narrow-minded again did with me last week? It gives me the feeling/confirmation of this thought deep down in my mind "Nobody needs YOU."
<beach> lotuseater: I long ago gave up trying to argue with people about things like that.
<beach> I find the only thing that kind of works in convincing people is to show that you can produce good work with less effort.
<lotuseater> Yes I thought of that too.
<hayley> beach: Well, for example, it is commonly said (outside of Lisp communities) that one can seriously make a mess out of metaprogramming facilities, so one should not use metaprogramming. The people saying those things do not believe anyone is competent enough to be reasonable in their use of metaprogramming.
<beach> hayley: I see. To me, that is more a reflection on their own competence than on that of others.
<lotuseater> Everything that such people do not know or understand has then automatically of course no meaning.
<hayley> So we have a contradiction wherein someone is supposed to either be good at program design, or is learning to make good decisions, but they also cannot be trusted to design anything.
<beach> Makes sense.
<beach> hayley: I understand programmers are mostly hired to follow orders and to be interchangeable, but that is a really dumb hiring practice in my opinion.
<hayley> Another thing I have been thinking about is that many people think programming is a hard and slow process, and only a few people can do it. So those people can come up with a lot of theories based on this assumption, and a language like Common Lisp can be useful in violating the former assumption.
<beach> lotuseater: I think that's a very typical sign of most humans.
<beach> lotuseater: However, I think that, as software developers, we have an obligation to fight such thoughts in ourselves. Of course, being able to do that already assumes that we are able to question our own abilities.
<lotuseater> Yes so widening the horizont is good.
<hayley> Now, it may very well be that hard problems remain hard. But then effort is spent thinking about what to do, rather than how to communicate it to the computer.
<Qwnavery> Programming is a tool. "Programmers" for better sense of a word, shouldn't exist. All corporate looks for are code monkeys, not individuals who can design, structure and implement systems.
<Qwnavery> It's why "products" like Windows exist.
<lotuseater> jap
<hayley> Recently I have been thinking about how the people who make such an assumption and write a lot based on it also espouse poor programming style. Of course, the direct result is that programming is hard for those people, but if they want to go around saying things based on this assumption, they need to make sure programming won't be easy.
<beach> Qwnavery: Sure, but those companies are in for a surprise. Apparently, there is a huge shortage of software developers on the horizon. I am thinking that this is an opportunity to tell companies about ways to improve productivity by using the right tools, and people with the right training.
<lotuseater> oh sry that should have gone to gilberth
<beach> lotuseater: gilberth is around?
<beach> hayley: Makes sense.
<lotuseater> yes I write with him in query since last week
<hayley> For example, some people I disagree with wrote that "the requirement of open source can [...] expose sensitive or secure information". Security by obscurity ain't security at all.
<lotuseater> as I got to know he's from Germany too
<beach> lotuseater: He is one of the best hackers I know.
<lotuseater> Oh I thought that. :) I can learn much from him.
<hayley> beach: I think there is some similarity with your "The psychology of learning" article.
<beach> hayley: Yeah.
<Qwnavery> beach: there will never be a shortage of code monkeys. Developers on the other hand... I feel like the biggest roadblock is shitty management. Corporate structure pushes arrogant and incompetent people to management positions. Even the best developers and software environment can't restructure that mess.
<hayley> And (as I now have some mental backlog) I agree that hiring for interchangeability is a bad idea.
<beach> Qwnavery: That doesn't seem to be the case. Apparently, the number of "programmers" doubles every 5 years. But teaching programs won't be able to keep up with that demand.
<lotuseater> No they call themselves mostly "software developers".
<Qwnavery> or worse yet; "software engineers"
<beach> Qwnavery: There is this myth that management decides what programmers do. But in reality, they have lots of freedom to do what they see fit, simply because management doesn't understand what they do. Few programmers seem to realize this though, and make mistakes such as ask for permission.
<hayley> Yesterday I started to think about the similarities in things I had critiqued before, and they seem to all make this initial assumption that programming is hard, so either programmers can't be trusted to design anything, or most people would never consider it.
<lotuseater> Better to ask for forgiveness. :)
<Qwnavery> hm.
<Qwnavery> I feel though that there is an alternative approach.
<hayley> "Good program design is, ultimately, the defiant insistence on acting as if one already is allowed to make drastic design changes." - probably not the late David Graeber
<White_Flame> people also tend to skip making prototypes
<White_Flame> and whatever emerges from that becomes their ad-hoc architecture
<lotuseater> beach: I bet gilberth would like to hear from you sometime again. :)
<White_Flame> which is now too entrenched to refactor and actually design
<Qwnavery> White_Flame: Recommend the TAO design Process.
<lotuseater> White_Flame: "no who needs prototypes, my stuff always works as intended directly ..."
<beach> lotuseater: I think you are right. We have met a number of times.
<Bike> oh, i didn't know graeber died
<hayley> Yes, you should plan to throw one out. Or two. Sometimes three. (Though yesterday, someone said you should always throw code out rather than design "good code", which is far too much.)
<beach> lotuseater: He is basically the reason McCLIM exists.
<hayley> Bike: Yeah, a pity.
blihp has quit [Quit: Leaving]
dtman34 has quit [Ping timeout: 258 seconds]
dtman34 has joined #commonlisp
Qwnavery has quit [Quit: WeeChat 3.2]
dsk has quit [Ping timeout: 252 seconds]
Bike has quit [Quit: Connection closed]
lisp123 has joined #commonlisp
khrbt has quit [Quit: ZNC 1.7.2+deb3 - https://znc.in]
khrbt has joined #commonlisp
khrbt has joined #commonlisp
khrbt has quit [Changing host]
khrbt has quit [Quit: ZNC 1.7.2+deb3 - https://znc.in]
khrbt has joined #commonlisp
taiju has joined #commonlisp
notzmv has quit [Read error: Connection reset by peer]
notzmv has joined #commonlisp
z3t0 has quit [Read error: Connection reset by peer]
d4ryus has quit [Quit: WeeChat 3.2]
d4ryus has joined #commonlisp
lisp123 has quit [Ping timeout: 248 seconds]
lisp-newbie has joined #commonlisp
lisp123 has joined #commonlisp
Lord_of_Life_ has joined #commonlisp
Lord_of_Life has quit [Ping timeout: 258 seconds]
Lord_of_Life_ is now known as Lord_of_Life
lisp123 has quit [Ping timeout: 268 seconds]
lisp123 has joined #commonlisp
lisp123_ has joined #commonlisp
lisp123_ has quit [Client Quit]
lisp123 has quit [Ping timeout: 268 seconds]
srji has quit [Read error: Connection reset by peer]
psycomic has joined #commonlisp
pve has joined #commonlisp
pranavats has left #commonlisp [Disconnected: Replaced by new connection]
pranavats has joined #commonlisp
pranavats has left #commonlisp [Disconnected: Replaced by new connection]
pranavats has joined #commonlisp
<psycomic> what's a good resource to understand the internals of the common lisp condition system? I'm making a programming language and I would like to a lisp-like debugger.
<moon-child> phoe wrote a book about it
<hayley> phoe's book The Common Lisp Condition System and the implementation presented.
<hayley> Though, really, the debugger only requires an INVOKE-DEBUGGER function.
<psycomic> thanks
lad has quit [Ping timeout: 256 seconds]
<beach> psycomic: What is unique about your language?
<psycomic> beach: Nothing, for the moment
<psycomic> i'm just making the virtual machine
<beach> psycomic: Also the Common Lisp "debugger" is not really one. It is just what I call a "backtrace inspector".
<psycomic> yeah, i know
nij- has joined #commonlisp
<psycomic> that's what i meant
dsk has joined #commonlisp
<beach> psycomic: I see. So what is the purpose of this language? Is it to teach yourself about language implementation techniques?
<beach> Or something else?
<psycomic> basically yes
<beach> Got it.
<psycomic> actually, it's the macro system of an assembler, integrated into my game engine
<beach> OK.
gaqwas has joined #commonlisp
<psycomic> i will use it for high level stuff, and use assembly for performance critical things
<psycomic> i could probably use guile or lua, but i wanted to try and implement my own lang
<beach> Language design is tricky business though.
<psycomic> i'm basically reading everything i can find before writing any code
<hayley> Doesn't hurt to take a stab at it still. Though using assembler for anything other than the hottest of hot loops is an interesting choice.
<moon-child> language design is heavily intertwined with implementation design
<moon-child> I agree about using assembly outside of inner loops
<beach> psycomic: I don't actually know of any literature on programming-language design. What are you reading?
<psycomic> beach: the lambda the ultimate papers, lisp in small pieces, essentials of programming languages, RABBIT: an optimizing compiler for scheme, and "the anatomy of lisp", but it's outdated
<moon-child> beach: I don't know of any literature either--though I'm sure some exists--but I have found discussions of language committees to be very instructive
<beach> I see. Mostly about implementing existing languages, it seems.
<beach> moon-child: Yes, that sounds like a good idea.
<psycomic> yep, not really programming language design, actually
<beach> psycomic: Right. I am making the distinction because you are creating your own language. And to me, making the right choices in language design is an order of magnitude more difficult than implementing an existing (well-designed) language.
<mfiano> Crafting Interpreters was just released, but I have not read it.
<mfiano> I have talked to the author about game development and language design a lot in the past, so I know he is competent to write about such a topic.
<hayley> When I skimmed it (in the years-long "draft" phase), it mostly discussed two implementations of a sort of Java-like language.
makomo has joined #commonlisp
<beach> mfiano: Good to know.
rain3 has joined #commonlisp
<psycomic> beach: i guess so. i'm also trying out different well designed programming languages, to have a better understanding of what makes a language good
<beach> psycomic: My current favorite example is the wish by plenty of relative newbies who wish that EVAL would have access to lexical variables in Common Lisp. Such a, seemingly innocent, decision would make it impossible to write optimizing compilers for Common Lisp.
<hayley> So it wasn't much of a language design book. That said, the author demonstrated a reasonable bytecode implementation.
<psycomic> beach: I'm not that much of a newbie
srji has joined #commonlisp
jans has quit [Remote host closed the connection]
<beach> psycomic: Hence "relative" :). And that is but one of many such suggestions that we have to argue about on a regular basis.
jans has joined #commonlisp
<hayley> While totally ridiculous, I wonder if you could use a lot of type splitting and inference to generate a fast path where you don't find a call to EVAL or get a reference to the EVAL function, and optimize that path.
<beach> Possibly.
<hayley> On the other hand, EVAL couldn't be a function if it has access to the caller's lexical environment.
<beach> psycomic: People can be experienced application programmers, and still have no clue about language design.
<beach> hayley: Why is that?
<psycomic> beach: what do you think are good example of good language design?
lisp-newbie has quit [Ping timeout: 258 seconds]
<beach> psycomic: Common Lisp is very good. They pushed the limits as much as they could without making it impossible to create good compilers. Python went one step too far.
<beach> psycomic: And most languages like Java don't go far enough.
<hayley> Correction, EVAL couldn't implicitly access the lexical environment of the caller, i.e. (let ((x ...)) (eval 'x))
lisp-newbie has joined #commonlisp
<beach> hayley: Why is that?
<hayley> I don't think there is a mechanism in Common Lisp which allows it.
<psycomic> beach: i guess by "going too far" you mean "being too dynamic"?
<beach> hayley: Oh, Common Lisp. Sure.
<moon-child> hayley: I think the assumption was a common lisp-like language where the mechanism was 'we said so'
<psycomic> python is basically scheme without parenthesis, though. And scheme has a lot of optimizing compilers.
<hayley> Right, Common Lisp.
<hayley> Er, no. Definitely not.
<beach> psycomic: Right. For example, if you can add slots to individual instances, you pretty much make it necessary to do slot access by hash tables, which gives you a factor 10-100 performance penalty.
<beach> psycomic: That's an example of a not-so-great decision.
<beach> [though there may be ways around it, of course, as I am sure #commonlisp participants will point out]
<psycomic> every object in python is a hash table?
<beach> I don't know how it is implemented. But no, Python is not essentially Scheme without parentheses.
<hayley> But PyPy does a decent job optimizing Python code. One could use something like Self maps/JavaScript "hidden classes"...and I think there is some weird class parameter which specifies a list of slot names.
<mfiano> Python is far from Scheme.
<hayley> https://docs.python.org/3/reference/datamodel.html#slots I think the existence of foo.__dict__ for some object foo basically forces you to use a hash table though.
<moon-child> inline caching is thattaway
<beach> psycomic: So I think we are getting close to some examples of what I mean.
<psycomic> what do you think about scheme, then. i personally like the design that tries to keep it simple and minimal (at the expense of being unpractical)
<hayley> moon-child: It is 2021, why are you only using monomorphic inline caching
d4ryus has quit [Quit: WeeChat 3.2]
<hayley> https://bibliography.selflanguage.org/_static/pics.pdf Oops, missed the 20th birthday of polymorphic inline caching.
<beach> psycomic: This is not the right forum for comparing languages, but I use generic functions every day, so I could not live without CLOS. But the, I guess Scheme is slowly acquiring more Common Lisp features.
<beach> *But then,
<White_Flame> *30th birthday?
<mfiano> Guile has a rather featureful CLOS
<mfiano> including a MOP
<beach> Yes, but Guile is not a language. It is a programming system.
<kakuhen> i find the metaobject protocol to be a really great extension
<hayley> White_Flame: Yeah, one of those.
<mfiano> It is a virtual machine for several languages
<mfiano> But yes, I meant Guile Scheme
<beach> It still has no independent standard.
<kakuhen> so-called """functors""" from C++ are just adding specifying the metaclass in CLOS, and then you make sure to add an instance function
<beach> psycomic: Which reminds me of a second example, namely that some people want generic dispatch to work on arbitrary types.
<kakuhen> in C++ you do nasty operator overload stuff just to pretend you have a funcallable object
<kakuhen> so that's one aspect of MOP I like a lot -- doesn't need to do things i find a bit gross heh
<psycomic> beach: doesn't ISLISP do that?
<beach> I don't remember. But generic dispatch on Common Lisp classes can be very fast.
<beach> General types are way more difficult, even from a semantic point of view.
<psycomic> method dispatch would be a lot harder
<mfiano> Dispatching on types is arguably more useful for static, nomimal type systems.
<beach> Yes.
<mfiano> CL is very dynamic with a (relatively) weird hybrid of nominal/structural types
<beach> psycomic: All I am saying is that design decisions like this can determine whether it is hard, or even impossible, to write a good compiler.
<beach> psycomic: That's why I was interested in your language, and your reason for creating your own.
<psycomic> i'll be careful then
<psycomic> but you gotta admit that very few "popular" languages actually care about good compilers
<psycomic> Javascript, Ruby, Python
<mfiano> Are any of those compiled?
<psycomic> bytecompiled
<mfiano> Sure, ok
<beach> psycomic: Yes, but then, that's no favor to the application programmer. For Python, you basically have to write C code to get performance.
<hayley> I would say type dispatch in Common Lisp is perhaps harder due to having AND and OR types. Oh, there's also SATISFIES. Good luck with that one.
<beach> psycomic: Python itself is estimated to be 50x slower than a good Common Lisp system.
<mfiano> hayley: ^^
<hayley> JavaScript has JIT compilers (V8 for example), Ruby has a JIT (which I didn't find to be that great in MRI, but TruffleRuby is great apparently), and Python has PyPy.
d4ryus has joined #commonlisp
<psycomic> well, thanks for the insight
d4ryus has quit [Client Quit]
<beach> Sure. Good luck!
<hayley> GraalVM also handles JavaScript and Python too.
d4ryus has joined #commonlisp
<hayley> In the context of JavaScript, I think the usual strategy is to use the usual optimizations (Lars Bak at least moved to the V8 compiler after Self) where applicable, and assume no one uses the non-optimizable stuff, which usually turns out to be true.
<hayley> That is in part because no one wants to be caught writing code that can't be compiled, so those developers just pretend those constructs don't exist.
hendursa1 has joined #commonlisp
hendursaga has quit [Ping timeout: 244 seconds]
Skyfire has quit [Quit: WeeChat 3.2]
dickbar__ has joined #commonlisp
d4ryus has quit [Quit: WeeChat 3.2]
<contrapunctus> Can client code add slots to an existing CLOS class, short of redefining the class entirely?
<hayley> Stealth mixins?
<beach> Adding a slot to a class basically amounts to redefining it.
<beach> contrapunctus: You would have to execute something like REINITIALIZE-INSTANCE on the class metaobject.
Qwnavery has joined #commonlisp
hendursa1 has quit [Remote host closed the connection]
<pjb> psycomic: well, invoke-debugger is the implementation-provided debugger function, but actually the power of CL debugging comes from *debugger-hook* #| --> #<function swank:swank-debugger-hook> |# which can be set to any function as you can see. Hence we can use different debuggers, possibly more sophisticated debuggers.
hendursa1 has joined #commonlisp
<psycomic> pjb: like the one in McClim? That's really interesting. Common lisp is even more flexible than i thought
<pjb> exactly.
<pjb> It's a general notion: languages are powerful in what they DO NOT provide. eg. C does not provide I/O operators. (pascal does: write, writeln) and for this reason is decried as less powerful than C, arguably rightly so.
Skyfire has joined #commonlisp
dsk has quit [Ping timeout: 245 seconds]
<psycomic> that's an interesting view of power
<contrapunctus> hayley, beach: would it be terrible if, instead of that, I had a plist/alist as a slot? (I'm trying to implement arbitrary properties for objects.)
<pjb> CL provides I/O operators, and this poses all kind of problems (eg. cannot switch easily between binary and text streams on stdio, listen works only on interactive (text) streams, etc.
copec has joined #commonlisp
<pjb> Yes. What saves lisp, is that it has macros, and most of the CL language is just defined with normal macros, that you can substitute for your own macros. So in a sense, lisp does not provide a language (C++ is like that too). Therefore even while the CL library provides some things, like I/O, this can be avoided, and replaced by custom code.
<psycomic> are they code examples of this? using *debugger-hook* to modify the debugger?
<pjb> C++ doesn't provide a (usable) programming language. Each shop has to define what subset of C++ they will use, what kind of smart pointer, what template library, etc. You need that to define the actual C++ derived programming language used at a given place.
<beach> contrapunctus: I think it all depends on your requirements in terms of flexibility, power, etc.
<psycomic> thanks!
<pjb> psycomic: swank is one such example.
<pjb> Note the result of *debugger-hook* #| --> #<function swank:swank-debugger-hook> |#
<psycomic> and in the command line, *debugger-hook* --> NIL
<psycomic> that makes sense
<pjb> In that case it uses the standard invoke-debugger function.
<pjb> Note that a custom debugger will have to use implementation specific API to inspect the stack, local frames, insert break points, etc. Some stuff can be done conformingly, but this require heavy lifting. Have a look for example at cl-stepper.
<psycomic> i see
dickbar__ has quit []
<pjb> good languages (languages that are easy to use and are powerful) feature: only expressions, no statement; only first class data types; homoiconicity; orthogonality.
<psycomic> pjb: very few languages are actually good if you go by that definition
<pjb> psycomic: for eaxmple, python or C are bad, because they distinguish statements from expression (eg. in C you have to write if(a==b){print("Yep");}else{print("Nope");} but you have to use print((a==b)?"Yep":"Nope") instead of print(if(a==b){"yep";}else{"nope";}); )
<beach> psycomic: That's why we use Common Lisp.
<pjb> for example, bash is bad because you cannot pass arrays to function, or store them in ararys, etc. (even string handling is badly implemented).
<beach> psycomic: Another essential feature is automatic memory management.
<MichaelRaskin> homoiconicity is overrated, reasonable and well-defined own-AST-representation/manipulation is more than enough
<psycomic> macros are not first class datatypes in common lisp, for obvious reasons
<beach> psycomic: A third one is "uniform reference semantics".
<mfiano> MichaelRaskin: I disagree. Just look at languages like Nim
<pjb> almost all languages are bad for lack of homoiconicity. Ruby has a way to represent identifiers as symbol, and a data syntax rich enough to represent code, but it's not homoiconic, so you have to convert the representation, and it's not pretty…
<pjb> and most languages are not orthogonal, in that they have all kind of special cases and contextual interdictions.
<MichaelRaskin> Nim has very weird compile-time sublanguage
d4ryus has joined #commonlisp
Fare has quit [Ping timeout: 258 seconds]
<pjb> Only lisp languages (and perhaps some very rare exception) match those critiria indeed.
<MichaelRaskin> Julia has macros done better than Common Lisp (sure, more expensively too) without formally speaking homoiconicity
<pjb> MichaelRaskin: a language can have macro. The question is whether you can easily implement a macro system in a language?
<pjb> Can you easily implement a macro system in Julia?
<psycomic> In Julia, you cannot use list functions on the AST, you have to create specific functions to work on the AST
<psycomic> that makes it inferior to lisp
<pjb> For example, you may not like the macro system of CL (unhigienic, etc) and may want to replace it. Can you do that in CL? Yes. Can you do that in Julia?
<MichaelRaskin> You cannot implement a macro system in any language without in-language support, short of writing an interpreter
<MichaelRaskin> You can only write a wrapper for CL macro system, not really a replacement, it has to resolve down to the native macro system.
<MichaelRaskin> (Same can be done in Julia)
<mfiano> Hmm. My favorite feature of CL hasn't been mentioned as a good language quality yet.
retropikzel has quit [Ping timeout: 256 seconds]
<pjb> I guess you'd have to use a pre-processor or wrapper, but in lisp it's trivial to do. In C, pre-processors are common, but they're relatively hard to do, since you have to write a (partial) C parser, and C pre-processors may not combine well (not orthogonal).
<pjb> See for example C programming language extension: Cedro pre-processor <https://sentido-labs.com/en/library/cedro/202106171400/>
<pjb> The only good C pre-processor is elpp ;-)
<psycomic> one of the most important feature of common lisp is that you can redefine anything at run-time
<psycomic> very few languages are that dynamic
* hayley was going to say "Late binding of all things"
cage has joined #commonlisp
<MichaelRaskin> For all this reference uniformity, the fact that you kind of effectively can turn this in a first class value but only via a closure is a bit annoying
<beach> psycomic: That is not true, and that's another good decision they made. You can not redefine standard operators.
<beach> psycomic: If you were allowed to redefine (say) CADR at run time, then the compiler could not make assumptions about the meaning of a form like (CADR x), and again, you would be limited in the kind of code you could generate.
<beach> psycomic: But thanks for giving another example of a possible bad design decision a "relative newbie" could make.
<psycomic> i didn't know that
<beach> The special operators are also fixed. You can not alter the meaning of LET.
<beach> Another good decision.
<psycomic> are all builtin functions like this?
<beach> Yes.
<White_Flame> well, you could shadow CL:LET with your own LOL:LET, so (let (....) ...) expands to something else, probably into CL:LET
<psycomic> i guess that makes sense
<White_Flame> *probably including CL:LET
retropikzel has joined #commonlisp
<beach> clhs 11.1.2.1.2
<specbot> Constraints on the COMMON-LISP Package for Conforming Programs: http://www.lispworks.com/reference/HyperSpec/Body/11_abab.htm
<beach> psycomic: ^
<beach> psycomic: The people who created Common Lisp were (are) very smart and very knowledgeable, and they seem to have taken all these things into consideration before making final decisions.
<psycomic> maybe i'll implement common lisp instead :-)
<mfiano> Meta-circularity is what I favor most. Being able to invoke any phase of the compiler in any other is unique and immensely powerful.
<beach> mfiano: Ah, yes.
cpu6502 has joined #commonlisp
<pjb> psycomic: notably, the CL standard allows for subset of CL (and also for supersets (extensions) of CL).
<pjb> psycomic: so it is a great idea to implement a subset of CL for a student project, since this allows you to implement it trivially in CL (often just by defining a package exporting only the operators of your subset), which helps you test your language and debug test programs even before you complete your own implementation!
<mfiano> I think it's a distinguishing feature of Lisps, or at least CL to have that kind of power. Macros are just a part of this functionality IMO.
<psycomic> pjb: but if i do that i miss on the most interesting thing: implementing the runtime
<mfiano> and it doesn't get nearly as much recognition when discussing Lisp features as it should
<pjb> psycomic: not at all. I'm talking of writing two implementation: one that is easy to do using CL, and one that you will have to debug, your own one.
<psycomic> ah, okay
<pjb> psycomic: but having both implementations is nice, since this let you compare them, and test unit tests on both. So you can validate your unit tests on CL, becofe using them to validate your implementation.
kakuhen has quit [Quit: Leaving...]
<beach> mfiano: I agree.
amk has quit [Remote host closed the connection]
<psycomic> yeah, that's clever. But i don't think i want to implement an existing language. I want to try out things, implement my own toy language and make design mistakes. It is the best way i found to learn
<mfiano> Everyone writes their own toy Lisp at some point. Enjoy
<beach> Now you know what will happen, so you are prepared.
<mfiano> When you are ready to put your toys away, CL is here (to stay)
amk has joined #commonlisp
<psycomic> also, on an unrelated note, how are lexical environments and closures optimized? I once wrote a scheme implementation that allocated frames on the heap, but there has to be a better way
<mfiano> lexical variables may not even be stack allocated
<mfiano> Depending on the implementation's register allocator
<mfiano> or the state of it rather
<beach> psycomic: Typically, a function object consists of code and a static environment. The latter typically in the form of a vector.
<beach> psycomic: Invoking the function object consists of passing the static environment as an implicit argument to the code.
<beach> psycomic: So the static environment is allocated on the heap, but only when the function object is created.
<beach> psycomic: Allocating frames is a different story altogether.
<beach> psycomic: A good Common Lisp system will use the processor stack for that.
<mfiano> register spilling is fun
<beach> psycomic: But Scheme is special because of first-class continuations, so for Scheme, it may be a better choice to allocate activation records ("stack frames") on the heap.
<psycomic> okay, thanks
<MichaelRaskin> \\
<mfiano> This is one of those times where I feel like I ought to learn/use Scheme more, not being familiar with first-class continuations at all. But I don't think I'd gain much by taking time away from CL :)
Giddy has joined #commonlisp
<MichaelRaskin> Well, first-class undelimited continuations _are_ a concept that you best learn in Scheme
<psycomic> mfiano: continuations are very interesting, and provide a way to optimize function calls
<mfiano> I admit I haven't read about CPS since compiler theory studies many years ago
<mfiano> Before I knew about Lisp
Giddy has quit [Client Quit]
<psycomic> you also get free coroutines, exceptions and nondeterminism
<beach> psycomic: I think you are confused.
Hdka has joined #commonlisp
<psycomic> how so?
<beach> psycomic: How do first-class continuations make it possible to optimize function calls?
Hdka has left #commonlisp [#commonlisp]
<psycomic> continuation passing style makes function calls simple gotos with arguments
<beach> psycomic: But that has nothing to do with first-class continuations. Only with whether the compiler optimized tail calls.
<psycomic> in CPS, everything is a tail call
<beach> You are not listening. *First-class* continuations are what is special in Scheme, and is manifested by CALL-WITH-CURRENT-CONTINUATION, and that is what makes the implementation of invocation records a more complicated decision.
<beach> psycomic: CPS can use an ordinary stack, and is used in Common Lisp implementations for representing intermediate code.
<psycomic> yep, you're right i'm confused
<psycomic> i missed the *first-class* in your sentence
<psycomic> my bad
<rain3> "This is one of those times where I feel like I ought to learn/use Scheme more, not being familiar with first-class continuations at all. But I don't think I'd gain much by taking time away from CL" but aren't delimited continuatios which we can use in CL more powerful than the universal continuations of Scheme? That's what I've heard
cpu6502 has quit [Quit: Textual IRC Client: www.textualapp.com]
<rain3> "delimited continuations are no less general than the regular ones. Regular continuations are also delimited, because they cannot capture control beyond the program's startup function. If we place a prompt at the top of the main function of the program and use that for making delimited continuations, we basically get regular continuations: continuations that can potentially return all the way to the top, just as far as regular
<rain3> continuations. (We can even set it up so that if any such a delimited continuation does actually get that far, the process will exit.) Delimiting is actually an extra bit of expressive power, not a constraint."
<rain3> '"Delimited" in continuations doesn't refer to a non-first-class hack. Delimited continuations are first-class, built-into-the-language objects (unless kludged otherwise, which is true of any continuations). They are just semantically nuanced relative to undelimited continuations in that they allow the program to clamp the future computation to within a specified dynamic contour. When the restarted continuation bubbles out to
<rain3> that boundary, it terminates and returns a value to whomever dispatched the continuation. And of course, it can be called again and again to do the same thing. That's why delimited continuations behave like functions and are composable.'
<beach> rain3: The point of Scheme-style first-class continuations is that you can invoke a continuation any number of times, with different inputs.
<beach> rain3: That power also makes it semantically complicated. Like do you re-open a file that was closed the first time you invoked the continuation when you invoke it a second time?
<beach> rain3: Do you un-execute the UNWIND-PROTECT forms that were executed?
<rain3> difficult problem, I have heard that's the reason CL chose not to have such continuations http://www.nhplace.com/kent/PFAQ/unwind-protect-vs-continuations-overview.html
<beach> Yes.
lisp-newbie has quit [Quit: This computer has gone to sleep]
<beach> Another design decision that was very likely carefully considered.
lisp-newbie has joined #commonlisp
shka has joined #commonlisp
taiju has quit [Ping timeout: 248 seconds]
taiju has joined #commonlisp
<rain3> mfiano: you may enjoy implementing this technique in CL https://pages.lip6.fr/Christian.Queinnec/PDF/www.pdf , it is almost trivial (and maybe useful in some apps too , I haven't used it much yet but I think it's good to have it in the toolkit)
random-nick has joined #commonlisp
Inline has quit [Quit: Leaving]
pranavats has left #commonlisp [#commonlisp]
CrashTestDummy2 has joined #commonlisp
nij- has quit [Ping timeout: 245 seconds]
CrashTestDummy3 has quit [Ping timeout: 248 seconds]
lisp-newbie has quit [Quit: This computer has gone to sleep]
lisp-newbie has joined #commonlisp
lisp-newbie has quit [Remote host closed the connection]
lisp-newbie has joined #commonlisp
lisp-newbie has quit [Remote host closed the connection]
tfeb has joined #commonlisp
Qwnavery has quit [Ping timeout: 248 seconds]
attila_lendvai has joined #commonlisp
pve has quit [Ping timeout: 268 seconds]
pranavats has joined #commonlisp
treflip has joined #commonlisp
CrashTestDummy3 has joined #commonlisp
tfeb has quit [Quit: died]
CrashTestDummy2 has quit [Ping timeout: 248 seconds]
Qwnavery has joined #commonlisp
Qwnavery has quit [Changing host]
Qwnavery has joined #commonlisp
Qwnavery has left #commonlisp [#commonlisp]
Inline has joined #commonlisp
kuler has quit [Remote host closed the connection]
kuler has joined #commonlisp
CrashTestDummy2 has joined #commonlisp
hendursa1 has quit [Remote host closed the connection]
CrashTestDummy3 has quit [Ping timeout: 248 seconds]
hendursa1 has joined #commonlisp
lisp-newbie has joined #commonlisp
waleee has joined #commonlisp
knobo has joined #commonlisp
nij- has joined #commonlisp
rain3 has quit [Ping timeout: 256 seconds]
frgo has joined #commonlisp
<mfiano> Thanks. I'll put it in my reading queue.
tyson2 has joined #commonlisp
gaqwas has quit [Remote host closed the connection]
treflip has quit [Remote host closed the connection]
<lotuseater> mfiano: Is yours also as long as it nearly reaches earth's moon?
<mfiano> Yes, and also my line of yaks waiting for a haircut reaches the horizon, and I have a recursive stove of back burners
lisp-newbie has quit [Quit: This computer has gone to sleep]
lisp-newbie has joined #commonlisp
sander has quit [Ping timeout: 256 seconds]
<lotuseater> Would like to help, but I'm sure you're out of reach.
amb007 has quit [Ping timeout: 268 seconds]
amb007 has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
<lisp-newbie> hi, how can I produce a symbol in a different package? https://quickref.common-lisp.net/alexandria.html#index-symbolicate
<mfiano> INTERN
sander has joined #commonlisp
amb007 has joined #commonlisp
<lisp-newbie> thanks,
amb007 has quit [Ping timeout: 248 seconds]
amb007 has joined #commonlisp
gaqwas has joined #commonlisp
gaqwas has quit [Remote host closed the connection]
gaqwas has joined #commonlisp
lisp-newbie has quit [Quit: This computer has gone to sleep]
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
amb007 has quit [Ping timeout: 268 seconds]
amb007 has joined #commonlisp
attila_lendvai has quit [Ping timeout: 245 seconds]
Fare has joined #commonlisp
rain3 has joined #commonlisp
pve has joined #commonlisp
Josh_2 has joined #commonlisp
hendursa1 has quit [Quit: hendursa1]
hendursaga has joined #commonlisp
<Josh_2> hi
<beach> Hello Josh_2.
gaqwas has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
amb007 has quit [Ping timeout: 268 seconds]
<pve> I keep hearing about how the people who designed CL were smart and knowledgeable, and that is very reassuring. But I'm curious, is there anything they got wrong?
<beach> Sure.
<beach> For one thing, they ran out of time.
<pve> I mean something that most experts would agree was a mistake
<pve> oh
<beach> Also the pathname module is not that great. It might have been at the time, but should perhaps have been left out.
<beach> It is also hard to distinguish mistakes from concessions to existing Lisp dialects.
tyson2 has quit [Remote host closed the connection]
cosimone has joined #commonlisp
gaqwas has joined #commonlisp
<pve> beach: I can imagine
<beach> pve: The work we started on WSCL is meant to fix the stuff that they likely would have fixed if they had not run out of time.
amb007 has joined #commonlisp
<pve> beach: Yes, I've been following the discussion with one eye.
<lotuseater> So the commitee got a deadline in 1984/94?
<mfiano> beach: Oh, did you see the discussion yesterday about something I found should probably be included in WSCL?
<beach> Briefly, yes. I made a mental not of it.
<beach> The "active elements in LOOP?
<beach> "active elements"
<mfiano> Yes. Currently it seems LOOP's ACROSS keyword is unspecified whether it iterates over inactive elements beyond a fill pointer
<beach> lotuseater: I don't know. I am just seeing all these things that I have no other explanation for, so I am guessing.
Fare has quit [Ping timeout: 272 seconds]
<beach> mfiano: Right.
<lotuseater> Oh okay. As you also told a while ago, the standardization did cost much money.
<mfiano> CLtL2 mentions something like "nearly everything except AREF" honor active elements only, but doesn't explicitly say how ACROSS is implemented, and this passage isn't in the HyperSpec at all.
tyson2 has joined #commonlisp
<lisp123> Is 5am the goto for unit testing, and does anyone have a good example repo to study when it comes to documentation / code organisation / testing?
<lisp123> I remember one floating around but I forgot now
<mfiano> lisp123: There is no go to unit testing library. See https://sabracrolleton.github.io/testing-framework
<beach> lisp123: The existence of so many libraries makes me think the entire abstracting idea is wrong.
<beach> *abstraction idea
<lisp123> mfiano: thanks for the link
<lisp123> beach: Sorry, I didn't quite follow
amb007 has quit [Ping timeout: 268 seconds]
<lisp123> beach: Do you mean that the number of testing libraries indicates everyone tends to do their own for their own needs and its hard to abstract away?
gin has joined #commonlisp
<gin> is it okay to type S-expression by hand into a file (foo.txt) and then load it using (with-open-file (in "foo.txt") (read in))? is this a good alternative for JSON?
Fare has joined #commonlisp
<mfiano> Whether it's better or not than JSON is easy: Yes. It's hard to say if it's a good idea for your project. It probably depends on how well you trust the source data, and whether you value compiler feedback earlier.
<MichaelRaskin> Also, remember about #.
<mfiano> Dynamically binding *READ-EVAL* can help with the former (though not completely).
<pve> not completely?
<mfiano> There's more that can blow up your image than evaluation.
<mfiano> For example, what if the untrusted source included something like "1d999"
<mfiano> Note: JSCL freezes the browser when this is read in the REPL.
<pve> mfiano: oh ok, I thought you were referring to MichaelRaskin's comment about #. .. sorry
<mfiano> Sandboxing CL is actually a fairly difficult problem without OS awareness
<MichaelRaskin> Then it could create a cyclic data structure, which might be fine or not dependig on your expectations
gaqwas has quit [Remote host closed the connection]
<mfiano> Imagine a large file with just a string of digits, being read in as a bignum that exceeds the heap size
Fare has quit [Ping timeout: 258 seconds]
<pjb> mfiano: imagine a small network socket doing the same. at least for the large file you can use file-length to put a bound.
<pjb> (unless *read-eval* is not nil).
<mfiano> CLISP's arbitrary precision floats with a large exponent then :)
gaqwas has joined #commonlisp
<beach> lisp123: Yes.
<lisp123> beach: Thanks
lisp123_ has joined #commonlisp
<gin> Thanks mfiano
<gin> what I needed to know was if it is okay to type a s-exp file by hand and load it using (read file). seems to work fine. not aware of any gotchas.
lisp123 has quit [Ping timeout: 248 seconds]
<gin> is there any popular extension name for such s-exp files?
<mfiano> You mean, (read stream)? Sure
<mfiano> Use .lisp
<mfiano> So your and other editors can be aware of the proper editing mode
<mfiano> others'*
<beach> gin: You don't "load" a file by using READ.
<mfiano> Or add the magic header comments for whatever editing environment you want to support
<gin> mfiano: thanks
<beach> gin: "loading" means reading it and evaluating the top-level forms.
<gin> beach: okay, so READ only does the "read" part of read-eval-print-loop? if so, makes sense now.
<gin> does the REPL also use the very same READ function to read s-exps?
<mfiano> Depends on the REPL
<mfiano> There is also read-from-string etc
<rain3> (time->string 3837526002 :format :y-m-d-hour-min-sec) ; does the name of this function violate any style rule ?
<mfiano> no?
<lisp123_> rain3: looks good to me
<lisp123_> sometimes I do time-to-string, but time->string is good too
<mfiano> I tend not to name functions with programming language types though, and use words from the problem domain instead.
<mfiano> Sometimes this cannot be helped, but I consider it a code smell in most cases.
copec has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<lisp123_> mfiano: my guess is in this case, he wants to convert time to strings so can't be helped
<lisp123_> sort of like a utility function (probably from get-universal-time and into something easier to read)
<rain3> thanks for the insights
lisp-newbie has joined #commonlisp
<mfiano> Well the name is still ambiguous.
<mfiano> TIME doesn't say anything of the structure of the input, and string doesn't say anything about the structure of the output.
<lisp123_> Do you have a suggestion?
Alfr has joined #commonlisp
<mfiano> Not really. These are questions I would ask when reading the code, especially if the documentation is not great.
<lisp123_> perhaps "ISO-time-string"
<lisp123_> I don't know, good luck rain3 :)
<mfiano> I have no idea if it's a universal time or what. I would rely on the documentation if I couldn't infer that from great named functions.
<rain3> it's general utility as lisp123_ said, a wrapper over get-universal-time
<rain3> so nothing to worry much about
<Josh_2> lisp123_: isn't this what local-time is for?
<lisp123_> Josh_2: I was going to suggest rain3 also look at local-time, but tbh I found it easier to write my own utility from get-universal-time (I can't remember why) - local-time I think is good for more advanced cases
<Josh_2> hmm
<Josh_2> I use local-time everytime I want to represent time, or do any sort of computations with dates
<lisp123_> (p.s. it would be good if a repl could be built into IRC) :D
<Josh_2> its just super convenient
<mfiano> As should everyone. It is a fantastic library.
<Josh_2> Yehp
<rain3> can local-time easily return strings in month-day-year or day-month-year or month.day.year (with dot) formats for example ?
<mfiano> sure
<lisp123_> Depends on how much _time_ you have :D
<lisp123_> If you just need a simple wrapper around get-universal-time, then just do that. But if you are working on a lot of time-sensitive things, might as well learn local-time
<rain3> good to know about it
<mfiano> (local-time:format-timestring nil (local-time:now) :format '(:month "." :day "." :year)) ; => "8.15.2021"
<mfiano> It's very flexible, for example if you want to pad the components:
<mfiano> (local-time:format-timestring nil (local-time:now) :format '((:month 2) #\. (:day 2) #\. :year))
<mfiano> "08.15.2021"
<lisp123_> Does anybody have an opinion on whether to define test systems in ASDF as a secondary system e.g. "foobar/test"
<lisp123_> ASDF best practices seem to suggest the former but I am seeing examples of the latter
<rain3> It would be useful to add those 2 examples by mfiano , to this page https://common-lisp.net/project/local-time/ or somewhere in the documentation
john__ has joined #commonlisp
<pjb> gin: you can use whatever extension you want. .sexp or .data or whatever.
<gin> pjb: thanks
<pjb> lisp123_: I just use foo.bar.test to test foo.bar, but foo-bar/test could be used too.
lisp123_ has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
lisp123_ has joined #commonlisp
<lisp123_> pjb: thanks
lisp123 has quit [Read error: Connection reset by peer]
Aksej has quit [Quit: ZNC 1.7.2+deb3 - https://znc.in]
john__ has quit [Quit: Leaving]
lad has joined #commonlisp
<jmercouris> anyone know a way to get profiling beyond sb-profile:profile
<jmercouris> I see how long my function takes
<jmercouris> but what about the functions that my function calls?
<jmercouris> I want to see how long those take as well
<mfiano> You're looking for the statistical profiler. See the manual
<jmercouris> I see
<jmercouris> thanks for the tip, will look
amb007 has joined #commonlisp
<lisp123_> Is there a way to force SLIME to load in the current window? Might be one of the most annoying things about Emacs not having decent behaviour for new buffers..
<lisp123_> slime-repl* that is
<lisp123_> Maybe I should just write some elisp to switch current buffer to *slime-repl sbcl*...will try that out now
<mfiano> That is one thing Sly handles better, but no, Emacs window management is hard to tame without things like purpose.el
<lisp123_> If anybody is interested - the above works when slime is already loaded, just press C-c s to switch to it in the current buffer
<lisp123_> current window*
amb007 has quit [Ping timeout: 256 seconds]
amb007 has joined #commonlisp
gaqwas has quit [Remote host closed the connection]
lisp-newbie has quit [Quit: This computer has gone to sleep]
khrbt_ has joined #commonlisp
khrbt has quit [Ping timeout: 258 seconds]
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
gaqwas has joined #commonlisp
waleee has quit [Ping timeout: 272 seconds]
waleee has joined #commonlisp
char has quit [Remote host closed the connection]
blihp has joined #commonlisp
<Josh_2> Is there a library around that will verify a file is the mimetype it claims to be?
<Josh_2> Specifically images
<mfiano> That is not really a solved problem period.
<Josh_2> Sure but checking the header of a file is better than not
<mfiano> Usually the magic bytes in the header of a binary file are few and easy to have false positives.
<Josh_2> What do you suggest I do? Just dont worry and make sure nothing is arbitrarily executed?
<mfiano> Probably easiest to just use uiop to call file(1)
<mfiano> The hard part isn't reading the file from lisp. It's knowing where and how much to read, and what to compare the results with
<mfiano> It's hard to say. I don't know what you are trying to do. If it's one file format, construct a full parse tree for you to type check :)
<Josh_2> Its not one file format ;(
<Josh_2> currently its png, gif, jpeg and zip, but its so easy to add new file types that I plan on adding compressed formats
<Josh_2> adding other*
<pjb> Josh_2: it's compounded by the problem that reading and validating any file format may also involve security bugs, and executing random code…
<pjb> Josh_2: (hence termination problem, hence unsolved problem).
<mfiano> Try loading them with opticl, chipz, or whatever and hope they have conditions to catch
<Josh_2> I think that might be what I have to do
<Josh_2> Thats basically what my system would do right now anyway because images are resized by imagemagick, so if they arent images then imagemagick will have a fit
<mfiano> This problem isn't possible to solve, really.
<mfiano> Mostly because anyone can create a file format, and implementors often get them wrong
<mfiano> Ever try parsing a later revision of MP3's ID3?
<Josh_2> Yes I understand
<mfiano> There are literally thousands of non-standard files, and a useful player has to support all the hacks to make them load
<mfiano> err thousands of variants
<mfiano> This is why web standards are a joke with browser wars and all
<Josh_2> Right
<Josh_2> I will just go with trying to open them with the relevant libraries/external programs and handle conditions
<Josh_2> Thanks for the info :)
<mfiano> Imagine a world where a Lisp implementation just has to be close to standard conforming, where "close" is up to the implementor :)
<mfiano> Luckily we all care about CL conformance enough to not make mistakes many others have
<lisp123_> Is there a way to confirm if a program is compliant with ANSI CL?
<lisp123_> I guess the issue is there are parts that are undefined
<pjb> lisp123_: the best way would be to run this program on all implementations and check that you get the same results.
<lisp123_> So to rephrase, is there a way to confirm a program is compliant with ANSI CL, once accounting for all undefined parts of the standard that are left up to the implementors choice
<lisp123_> pjb: Yes, that I agree. But I wonder if its possible to check a program and all its dependencies against the Standard
<lotuseater> so *all* implementations :D
<pjb> not really, because you can still use operators that have implementation specific behavior, but the checking of the results depends on the specifications of the program.
<lisp123_> pjb: Understood, thanks
<pjb> For example (defun main () (print (length (lisp-implementation-type)))) (main) will print an integer with different values. What are the specifications of this program?
<pjb> If the specification is to print SOME integer representing the lenght of the implementation type string, then it's ok and conforming. If the spec is to print 4, then it works only in sbcl, therefore it's not conforming.
<lisp123_> I was wondering if one could split the evaluation into parts that are per the standard, and into parts that are implementation dependent
<lisp123_> But I guess its too tall of an ask
<mfiano> Also note that no implementation is fully conforming, so code you write likely will not be either.
<mfiano> A prime example is the many errors with MIT LOOP, which most implementations derive from
<lisp123_> Thanks
<pjb> lisp123_: definitely. But this is unrelated to the conformity property of a program.
<pjb> As my exemple demonstrate, conformity depends on the specifications of the program.
boeg has joined #commonlisp
<boeg> How would i go about filtering out non-alphanumerical characters in a string?
<mfiano> remove-if-not
<boeg> ah
<pjb> Now, perhaps you can perform some static analysis of CL code and determine that some expressions are conforming in the absolute.
<boeg> mfiano:
<boeg> mfiano: thanks
<pjb> lisp123_: ^ but I'd guess very few of them would be tagged as such.
<mfiano> boeg: (remove-if-not #'alphanumericp "hello-world-123") ;=> "helloworld123"
<lisp123_> pjb: Yes, that's what I was thinking. But I agree with you that very few would be tagged as such I guess - if a return value is implementation dependent, then any function calling that would also be 'tainted'
<pjb> lisp123_: For example, (= 42 (answer-to-the-big-question-of-the-universe-and-all)) will return an implementation-specific value. Even if the function answer-to-the-big-question-of-the-universe-and-all is 100% conforming at all step, the final result is not the same on all implementations.
<pjb> lisp123_: = returns a generalized boolean, not T or NIL. So the actual result can vary from implementation to implementation.
<lotuseater> boeg: and #'alphanumericp :)
<mfiano> lotuseater: like i said
<boeg> :)
<lotuseater> oh damn, sorry mfian
<pjb> To have an expression that would definitely be conforming whatever its specifications and the implementation, you'd have to do a lot of extra work, such as (not (not (= 42 (answer-to-the-big-question-of-the-universe-and-all))))
<lotuseater> i overread that
<lisp123_> pjb: Damn, something as basic as #'= can cause such (subtle) variations :(
<pjb> and prove that answer-to-the-big-question-of-the-universe-and-all returns the same on all implementations.
<lotuseater> but i remember back when i missed filter
<lisp123_> Possibly a good LaaS (Lisp as a Service) would be to take some code and test it in every implementation
<lisp123_> pjb: Thanks for the insight
<pjb> The point about generalized booleans is that in general, it doesn't matter, since you just test the result and go on.
<lotuseater> but surely one can do (setf (symbol-function 'filter) #'remove-if-not) if it should provide the same API with its key args
<pjb> But the program you will write to determine if an expression is conforming in the absolute, won't be very stable (and you need to solve or avoid the termination problem).
<mfiano> lotuseater: But..but..but
<pjb> lisp123_: the tainting depends on what the calling function does of the result. So it can be processed.
<lisp123_> Can you expand on the last part?
<mfiano> REMOVE-IF-NOT is DEPRECATED. We have to be prepared for the next standard!
<lotuseater> mfiano: yes I know :D
<lotuseater> it is? o_O
<pjb> lisp123_: basically, I'd expect the program to determine, yes, no, yes, no, yes, no, etc or about, for each embedded subexpression.
<mfiano> remove-if/complement solves that, for whoever the hell cares
<pjb> (conforming (not-conforming (conforming (not-conforming …))))
<lotuseater> one must be careful and think when to use remove-if or remove-if-not
<mfiano> Lisp ain't changing, so I don't
<lotuseater> yes and that is wonderful!
<lisp123_> pjb: Yes. So by 'termination problem' do you mean any potential issues with recursion?
<pjb> or loops.
<mfiano> to be honest, I find the "filter" terminology ambiguous
<mfiano> am i filtering out stuff, or what?
<lisp123_> THanks, understood
<mfiano> i never liked that term :)
<lisp123_> Appreciate it
<pjb> lisp123_: and then, real programs use extensions such as threads, gray streams, sockets, etc…
<lisp123_> mfiano: Worst part is I don't think there is an official function for filter :S
<pjb> But you can still write a conforming program but it's even harder to prove it.
<mfiano> lisp123_: we mentioned it is remove-if-not, a much better name
<lotuseater> yes and I was used to filter in Haskell before, it just takes a lambda and a list
<pjb> (defun filter (predicate list) (remove-if-not predicate list))
<pjb> be happy!
<akater[m]> I hope `-if-not` functions don't get wiped. `:test-not` probably should go but functions are fine.
<lisp123_> pjb: For that I was thinking of applying the same conforming test to those extensions (but after this discussion I agree that this idea of conformance checking is not feasible)
<lotuseater> lisp123_: you can do as you please in your personal packages or utility libs of course :)
<akater[m]> pjb: Is `(setf (fdefinition 'filter) #'remove-if-not)` not recommended?
<lisp123_> lotuseater: Indeed. Right now I don't have a filter function there, I forgot how I did when I need it
notzmv has quit [Ping timeout: 252 seconds]
<lotuseater> akater[m]: the example of pjb hides away the keywords
<mfiano> (remove-if (complement #'alphabumericp) string)
<mfiano> there, no remove-if-not
<mfiano> (not even indirectly)
<pjb> lisp123_: but in practice, if you run your program on several implementations and find the same results, you're quite good.
<lotuseater> lisp123_: or sometimes when one needs TAKE-WHILE and DROP-WHILE
<pjb> lisp123_: do as in the shuttle: have 5 different implementations, and let them vote for the results.
<lotuseater> ooh right, COMPLEMENT
lisp-newbie has joined #commonlisp
<lisp123_> pjb: Indeed :)
retropikzel has quit [Quit: Leaving]
<pjb> akater[m]: you can do it, (setf fdefinition), but the compiler wouldn't know it's a function, so it would keep warning about undefined function filter.
<pjb> akater[m]: you'd have to add a (declaim (ftype (function (t t) t) filter))
cosimone has quit [Ping timeout: 272 seconds]
<lotuseater> or more declaiming that the first argument is a boolean function ^^
<pjb> No that would be an error. (filter 42 'foo) will signal an error. If you declare that the first argument is a function, then (filter 42 'foo) may crash.
<lotuseater> ah so remove-if-not can also do that
<lotuseater> I wasn't aware of that detail.
<lotuseater> ah i think it's because everything except nil has ⊤ as superclass
<pjb> (typep 'nil 't) #| --> t |# (subtypep 'nil 't) #| --> t ; t |#
<lotuseater> ha.
<lotuseater> also more flexible
<lotuseater> ⊤ and ⊥ :)
<akater[m]> lotuseater: “function designator” is the proper term but there is no such type by default.
Fare has joined #commonlisp
<lotuseater> okay
<jmercouris> mfiano: don’t get me started talking about web standards
<jmercouris> You’ll throw me into a blind rage
<lotuseater> jmercouris: there are serious web standards? :D (of course there are)
<jmercouris> Are there though?
<jmercouris> The only one I take seriously is http
<lotuseater> yes I mean such things that are there for a long time
<lotuseater> and of course the great standardized javascript and its frameworks
lisp-newbie has quit [Quit: This computer has gone to sleep]
lisp-newbie has joined #commonlisp
lisp-newbie has quit [Client Quit]
<Josh_2> Does anyone know how I can generate output like <style scoped> ... </style> with spinneret?
<Josh_2> Closest I have gotten is <style scoped=''> ... </style> which doesn't work :(
attila_lendvai has joined #commonlisp
<gin> Is there a way to make quicklisp write to a .cache/ directory I specify?
tyson2 has quit [Quit: ERC (IRC client for Emacs 27.2)]
rain3 has quit [Ping timeout: 272 seconds]
<susam> gin: It is ASDF that tries to write to ~/.cache/ when you load Quicklisp. The default cache location can be overridden by specifying XDG_CACHE_HOME environment variable. See https://wiki.archlinux.org/title/XDG_Base_Directory for details.
<mfiano> jmercouris: I stopped writing on the web and moved to gemini :)
tophullyte has joined #commonlisp
Fare has quit [Ping timeout: 272 seconds]
kuler has quit [Remote host closed the connection]
pve has quit [Quit: leaving]
<mfiano> I need help figuring out why SBCL detected this DCE. My brain is not picking up on it
<mfiano> Any takers?
akoana has joined #commonlisp
<lotuseater> what does DCE stand for in this context?
<mfiano> Dead Code Elimination
<lotuseater> ahh
lad has quit [Ping timeout: 256 seconds]
<Josh_2> Send away
cage has quit [Quit: rcirc on GNU Emacs 27.1]
khrbt has joined #commonlisp
khrbt_ has quit [Ping timeout: 252 seconds]
tophullyte has quit [Quit: Leaving]
<mfiano> Oh huh. It's because it doesn't like it when ABS is bound to REL's binding in the parameter list.
<mfiano> Must be an algorithmic problem
notzmv has joined #commonlisp
karlosz has joined #commonlisp
dilated_dinosaur has quit [Ping timeout: 272 seconds]
selwyn has joined #commonlisp
dilated_dinosaur has joined #commonlisp
john__ has joined #commonlisp
gaqwas has quit [Ping timeout: 248 seconds]
khrbt_ has joined #commonlisp
khrbt has quit [Ping timeout: 272 seconds]
attila_lendvai has quit [Ping timeout: 248 seconds]
psycomic has quit [Ping timeout: 272 seconds]
sander has quit [Quit: So long! :)]
dsk has joined #commonlisp
sander has joined #commonlisp
lisp123_ has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
Volt has joined #commonlisp
lisp123 has quit [Ping timeout: 256 seconds]
<pjb> mfiano: it's because either (%%= e1 e2 …) is true or not, the function %= will always return nil. Since %%= doesn't have any side effect (sbcl can prove it since it's inlined), then it's useless to evaluate it: it's dead code.
<pjb> mfiano: the only thing that may be left are type checks, but if you've declared the type of data or if sbcl can prove e1 and e2 and rel and abs are real, then there's no type error.
<pjb> or if you use safety 0…
selwyn has quit [Read error: Connection reset by peer]
<pjb> mfiano: ah, the joy of using a smart compiler!
lisp123 has joined #commonlisp
<mfiano> pjb: that's not true
<pjb> You have a better theory?
<mfiano> it only returns from %= with a NIL if ANY call to %%= returns NIL, otherwise hits the T at the end
<mfiano> I explained the problem above
<mfiano> It was due to the parameter binding
<pjb> Oh, sorry, I didn't see the T.
<mfiano> It is somehow solved by changing line 3
<mfiano> from (abs rel) to (abs 1d-7)
<pjb> But (abs rel) is legal AFAIK.
<mfiano> So I have to re-evaluate my algorithm
<mfiano> Yes it is, which makes me question the algorithm
<pjb> If just s/abs rel/abs 1d-7/ is enough to make good, then there's a bug in sbcl.
<mfiano> Then I guess there is
<mfiano> I have been trying to track down the cause
<mfiano> Yeah seems to be pointing to a hard to reproduce bug
<mfiano> I'll just hack around it for now. Can't be bothered anymore
makomo has quit [Ping timeout: 256 seconds]
dra has joined #commonlisp
wilfred has joined #commonlisp
akoana has left #commonlisp [Leaving]
jans1 has joined #commonlisp
makomo has joined #commonlisp
jans has quit [Ping timeout: 256 seconds]
jans1 is now known as jans
Fare has joined #commonlisp
frgo has quit [Remote host closed the connection]
frgo has joined #commonlisp
john__ has quit [Ping timeout: 248 seconds]
karlosz has quit [Quit: karlosz]
cjb has joined #commonlisp
notzmv has quit [Ping timeout: 268 seconds]
shka has quit [Ping timeout: 256 seconds]
<jcowan> beach: And yet JS, which started out with objects-as-hash-tables, is now heavily optimized on the fly. It most certainly is not impossible to be fast
<jcowan> in highly dynamic languages
Alfr has quit [Quit: Leaving]
dra has quit [Quit: Leaving]
taiju has quit [Ping timeout: 256 seconds]
taiju has joined #commonlisp
taiju has quit [Ping timeout: 272 seconds]
taiju has joined #commonlisp
kakuhen has joined #commonlisp
Demosthenex has quit [Ping timeout: 258 seconds]
CrashTestDummy2 has quit [Quit: Leaving]
tyson2 has joined #commonlisp
taiju has quit [Ping timeout: 268 seconds]
john__ has joined #commonlisp
taiju has joined #commonlisp
<pl> jcowan: this involves, at times, a bit esoteric knowledge about details of implementation leaking out from abstraction
<pl> for example, I have a book somewhere which talks about manual optimizations (i.e. structuring code so that optimizer can work) related to underlying method resolution algorithm
Demosthenex has joined #commonlisp
<hayley> Yeah, the optimization (hidden classes) only works if you don't change the set of slot names. Fortunately I don't think anyone does that.
<hayley> *slot names frequently
<moon-child> compare a language where you're not _allowed_ to change the set of slot names to one where you can, incurring a performance penalty only when you do
<moon-child> have you lost anything in moving to the latte rlanguage?
<jcowan> "C-style syntax", of course.
<moon-child> well, assuming languages which are otherwise equivalent
<moon-child> a hypothetical version of js where the slotset is fixed; or a hypothetical version of cl where you can add and remove slots dynamically
CrashTestDummy has joined #commonlisp