jackdaniel 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> | Pastebin: <https://plaster.tymoon.eu/>
causal has joined #commonlisp
sjl has quit [Quit: WeeChat 3.3]
orestarod has quit [Ping timeout: 268 seconds]
NotThatRPG has joined #commonlisp
Fare has joined #commonlisp
deadmarshal has quit [Ping timeout: 268 seconds]
tyson2 has quit [Ping timeout: 268 seconds]
ebrasca has quit [Remote host closed the connection]
deadmarshal has joined #commonlisp
akoana has quit [Quit: leaving]
alvaro121_ has joined #commonlisp
alvaro121 has quit [Ping timeout: 252 seconds]
Fare has quit [Ping timeout: 245 seconds]
Catie has quit [Remote host closed the connection]
Oddity has joined #commonlisp
frgo has quit [Ping timeout: 244 seconds]
dilated_dinosaur has quit [Ping timeout: 244 seconds]
SR-71 has quit [Ping timeout: 244 seconds]
dilated_dinosaur has joined #commonlisp
azimut has joined #commonlisp
hineios5 has joined #commonlisp
hineios has quit [Ping timeout: 268 seconds]
hineios5 is now known as hineios
karlosz has quit [Ping timeout: 252 seconds]
gateway2000 has quit [Quit: Leaving]
dBc has joined #commonlisp
son0p has quit [Ping timeout: 268 seconds]
karlosz has joined #commonlisp
SR-71 has joined #commonlisp
azimut has quit [Ping timeout: 268 seconds]
Nilby has quit [Ping timeout: 255 seconds]
<SR-71> An intresting tool
<SR-71> Another intresting one indeed.
dtman34 has quit [Remote host closed the connection]
dtman34 has joined #commonlisp
pve has joined #commonlisp
karlosz has quit [Ping timeout: 252 seconds]
rainthree has joined #commonlisp
son0p has joined #commonlisp
<rendar> why apply wants #'+ specified with #?
<beach> It doesn't.
<beach> The first argument of APPLY is a "function designator".
<beach> From the glossary, we learn that a "function designator" is either a function object or a symbol.
<beach> Of course #'<name> and '<name> can refer to different functions.
_cymew_ has joined #commonlisp
<rendar> hmm, i see
<beach> #'<name> is taken by READ to be a reader macro, so READ returns (FUNCTION <name>) whereas '<name> is taken by read to be a different reader macro so READ returns (QUOTE <name>).
<rendar> i see!
irfan has joined #commonlisp
<rendar> read is what reads every list args?
<beach> READ is what reads all code.
<rendar> i'm trying to call read, it seems read the code from stdin
<beach> clhs read.
<specbot> Couldn't find anything for read..
<beach> clhs read
<rendar> ok
<beach> As you can see, you can specify the stream to read from.
Brucio-61 has quit [Remote host closed the connection]
Brucio-61 has joined #commonlisp
scymtym has quit [Remote host closed the connection]
scymtym has joined #commonlisp
SR-71 has quit [Ping timeout: 244 seconds]
<beach> rendar: READ turns a sequence of characters into a data structure in memory that we call an S-expression. An S-expression is either an atom or a CONS cell containing an S-expression it its CAR slot and another S-expression in its CDR slot.
<beach> rendar: The evaluator does not handle sequences of characters, but these S-expressions.
aartaka has quit [Ping timeout: 268 seconds]
dBc has quit [Quit: leaving]
<rendar> ok, i see
<rendar> basically also CONS create a s-expr
<beach> Yes, you can say that. It creates a CONS cell that contains its first argument in the CAR slot and its second argument in the CDR slot.
<rendar> yep
<beach> I mentioned what READ does, because the other day, from what you said, it seemed that you were mixing up reading and evaluation.
_cymew_ has quit [Quit: Konversation terminated!]
<pve> Hi, do any of the commonly used utility libraries (e.g. alexandria) provide this utility, perhaps under a different name?
<pjb> pve: it could be just (define-namespace recipe), the variable name could be a gensym too. Otherwise no, it's not a general enough concept.
<pjb> pve: utility libraries will contain functions that appears in almost every program.
<pjb> pve: but you could definitely put define-namespace in your own utility library.
<pve> pjb: ok thanks, I included the variable name because I think I prefer defvar here, so existing entries won't be clobbered if the form is re-evaluated
<pve> although I didn't give it much thought yet.. your gensym idea is good, so I might do that
frgo has joined #commonlisp
lottaquestions has quit [Quit: Konversation terminated!]
lottaquestions has joined #commonlisp
<pjb> (let ((varname (gensym))) `(progn (defvar ,varname …) (defun … ,varname …) ',name))
<pjb> the advantage of using a gensym here (or make-symbol), is that since the variable name is not interned, it cannot be used outside of the code generated by the macro, so you're safe from interferences or side-effects from outside.
<pve> yes I see, but just to be clear: re-evaluating that will effectively erase existing entries?
karlosz has joined #commonlisp
<kakuhen> depends on what you're invoking; defvar will assign to a dynamic variable if it's unbound, otherwise it doesn't change the binding
<kakuhen> defparameter has the opposite behavior: always assigns a given initial value to a dynamic variable
<pve> I mean we defvar a new gensym each time and point the functions to it, no?
karlosz has quit [Quit: karlosz]
<pjb> pve: yes, since a new variable will be used.
<pjb> pve: alternatively, you could store the hash-table in the symbol-plist of the name of the namespace.
<pve> pjb: aha! interesting alternative..
jmd_ has quit [Ping timeout: 240 seconds]
puhi has quit [Quit: (;´Д`)]
puhi has joined #commonlisp
gxt___ has quit [Remote host closed the connection]
gxt___ has joined #commonlisp
random-nick has joined #commonlisp
gateway2000 has joined #commonlisp
Dynom_ has joined #commonlisp
Dynom_ is now known as Guest563
rodicm has joined #commonlisp
rodicm has quit [Quit: Leaving]
xaotuk has joined #commonlisp
gateway2000 has quit [Quit: Leaving]
euandreh has quit [Ping timeout: 245 seconds]
aartaka has joined #commonlisp
orestarod has joined #commonlisp
cage has joined #commonlisp
xaotuk has quit [Quit: xaotuk]
<jcowan> beach: The term "S-expression" seems to be incurably ambiguous: it can mean an internal representation or an external one. (The question of what these representations represent I leave to Kantians.)
<beach> Good to know.
<_death> ambiguity can easily be cured.. s-expression(1) and s-expression(2)
<beach> jcowan: Did you seriously think I didn't already know that?
<jcowan> I was going to add that it is probably not a pedagogically useful term, that's all
gxt___ has quit [Remote host closed the connection]
<jcowan> (but I got distracted, sorry)
gxt___ has joined #commonlisp
<hexology> maybe it's good to come up with an alternative term for the "internal" variety (hy calls it a "model"), then define terms unambiguously and adhere strictly to the distinction
<hexology> i can't speak for lisp specifically, but i find that this is a useful communication technique in fields with confusing terminology. it's a local lexical binding but for language :)
<random-nick> why would s-expression mean an internal representation? as far as I know those are called lists
<beach> random-nick: Most atoms are not lists, yet, they are S-expressions.
<hexology> i suppose "form" is also overloaded in the same way?
<beach> No, "form" is an S-expression meant to be evaluated.
<_death> lisp terminology has been around for a long time, so a person who has been sufficiently exposed to it has a good sense of the channel transition matrix for practical block lengths
<random-nick> the standard calls them expressions, not S-expressions iirc
aartaka has quit [Ping timeout: 245 seconds]
<hayley> Using the definition "an S-expression is either an atom or a CONS cell ..." how is an "S-expression" different to, say, an "object"?
<beach> I find it interesting that some people have opinions about pedagogy, yet instead of using those opinions to teach newbies about Common Lisp, they seem to wait until someone else does, only to complain about the pedagogical techniques used by that someone else.
rainthree has quit [Ping timeout: 245 seconds]
<beach> hayley: There is no difference.
<hayley> Okay, thanks.
<beach> hayley: The glossary says expression "1. an object,...".
Oddity has quit [Ping timeout: 240 seconds]
<hayley> Just asking, since a few days ago I got into a "discussion" which involved confusing internal and external representations, and the two "layers" of Lisp syntax, and would like to avoid having that experience again.
<beach> Right, you have to make the distinction explicit.
vassenn has joined #commonlisp
aartaka has joined #commonlisp
<hayley> In particular, someone was trying to tell me that one could encode any data types using S-expressions (with just lists, symbols and numbers and such). They are correct, but they wrongly claimed it was specific to S-expressions; I don't think it is, because one would need their own "evaluator" of sorts to produce a graph of objects from the list structure read. One could do just the same with any other syntax.
<hexology> beach: i hope i didn't give you the impression that i was complaining. that was not my intention.
<beach> I can't say I much care anymore. I am getting used to this state of things. Or rather, I now know what to expect.
cage has quit [Remote host closed the connection]
<hayley> On the other hand, the S-expression syntax (or first layer of syntax) is quite permissive, and one can read forms that don't make any sense as Lisp code. But I wouldn't be so bothered if I had to encode everything as a function call, if I had to use some other syntax. Say, writing (person "Hayley" (in "#lisp")) isn't profoundly better than person("Hayley", in("#lisp")) or something like that.
<hayley> (We could indeed use reader macros, as is done in Cleavir, to introduce syntax that denotes objects, but I had the sense that I was talking to (or, "past") someone who had an idealised notion of "Lisp" rather than any particular language, because they couldn't distinguish between internal and external representations.)
<hexology> hayley: i think the thing about s-expressions is that a(b, c, d) is a very unnatural way to represent a list in writing, while (a b c d) more or less looks like "a list of things"
<hayley> In this example, person(...) does not denote a list, though, it denotes some information about a person. A list is one of many kinds of things one might want to represent.
azimut has joined #commonlisp
<hexology> fair. i tend to make the mental distinction between "collections" and "records"
<_death> what about (a . (b . (c . (d . nil))))
<hexology> i don't hate the clojure mindset here, of breaking the equivalence between s-expr "lists" and null-terminated-singly-linked-lists
<hexology> re: person(...) vs. (person ...), it was a pretty eye-opening moment when i realized that you couldn't effectively write a static analyzer (e.g. a tree-sitter grammar) for an s-expr language and expect to be able to highlight function calls, provide sensible indenting, etc. without encoding lots of special cases
<hexology> static analysis seems to be the biggest deficiency of highly-uniform syntax. you need some kind of runtime information and/or a big list of special cases.
<hayley> Still, though, (person "Hayley") is a list, which might denote information about myself under some interpretation. In a way the first interpretation is just "syntax", and the latter is "semantics".
<hexology> i agree with you there
morganw has joined #commonlisp
<hayley> With regards to analysis: you "just" need to reason about the second (or now "semantic") layer of syntax. I don't know how easy that would be with libraries that seem designed for a single-layer syntax. But, in a way, an evaluator needs to "parse" the list structure to figure out what action it should take; a syntax highlighter should do the same.
<hayley> (Lots of scare quotes tonight.)
<hexology> right, well-said
<hexology> vim has a pretty clever "lispwords" system for indenting lisp-like languages, idk if emacs has an equivalent
<hayley> A friend wanted to write an implementation of a language using S-expressions for some assignment work, but had to produce a single-layer syntax. They sent me the parser code and it was quite nasty. Imagine having separate rules for DEFUN forms, LET forms, and such. Though I've seen similar in published code, unfortunately.
<hayley> (And when that parser is written by hand in an unsafe language, fuzzing will find somewhat amusing crashes most of the time, because of the sheer number of cases that one has to implement without making mistakes.)
<morganw> I think emacs is the opposite, the built-in parser is originally for lisp and things get more difficult the further removed you get from lisp.
<jcowan> beach: I intended no offense, but in fact one does not need to be a carpenter to point out that a table wobbles.
igemnace has joined #commonlisp
<hayley> morganw: Suppose I want to model decay, and I write something like (let ((lambda 0.5)) (expt lambda time)). The "lambda" just before "0.5" is highlighted like it starts a LAMBDA form, when it doesn't.
<hayley> (The highlighting seems correct in emacs-lisp-mode, but I still get information on the LAMBDA special form in the mini-buffer, which is wrong.)
<morganw> For me the doc prompt in the mini-buffer is "expt: (ARG1 ARG2)".
<hayley> While I have my cursor over "lambda" specifically.
<morganw> Oh, yes, for the first lambda is does show documentation for lambda
<hayley> (Or perhaps I should have written (let ((lambda 0.5)) (exp (* -1 lambda time))) but that doesn't really matter.)
<morganw> The documentation mode is a separate part, I'd guess it isn't using all of the parser information.
rainthree has joined #commonlisp
<morganw> Looking at eldoc-documentation-strategy it looks like it is more of a best guess.
gateway2000 has joined #commonlisp
jcowan has quit [Excess Flood]
jcowan has joined #commonlisp
<White_Flame> rendar: for playing around with the reader to see what it does, (read-from-string "'(foo #.(+ 1 1))") might be an easier interface, which streams from the string you give. As well as (setf *print-pretty* nil) so you can see the raw gory details printed
<beach> Good advice.
MajorBiscuit has joined #commonlisp
MajorBiscuit has quit [Read error: Connection reset by peer]
euandreh has joined #commonlisp
MajorBiscuit has joined #commonlisp
MajorBiscuit has quit [Read error: Connection reset by peer]
igemnace has quit [Remote host closed the connection]
Fare has joined #commonlisp
Posterdati has quit [Quit: KVIrc 5.0.0 Aria http://www.kvirc.net/]
gateway2000 has quit [Quit: Leaving]
puhi has quit [Quit: (;´Д`)]
puhi has joined #commonlisp
Fare has quit [Ping timeout: 252 seconds]
vassenn has quit [Quit: Good bye!]
Posterdati has joined #commonlisp
azimut has quit [Remote host closed the connection]
puchacz has joined #commonlisp
pranavats has left #commonlisp [Error from remote client]
irfan has quit [Quit: leaving]
trocado has quit [Ping timeout: 252 seconds]
tyson2 has joined #commonlisp
azimut has joined #commonlisp
puchacz has quit [Quit: Client closed]
Lord_of_Life has quit [Ping timeout: 245 seconds]
Lord_of_Life has joined #commonlisp
morganw has quit [Remote host closed the connection]
aartaka has quit [Ping timeout: 252 seconds]
aartaka has joined #commonlisp
rainthree has quit [Ping timeout: 268 seconds]
szkl has quit [Quit: Connection closed for inactivity]
<rendar> White_Flame, very interesting thanks
<rendar> i'm not so expert to understand #.
tyson2 has quit [Remote host closed the connection]
jmdaemon has joined #commonlisp
<pjb> rendar: #. reads an expression, evaluates it, and returns its result as the object read by #.
<pjb> rendar: so: (quote (#.(+ 1 2) #.(* 3 4))) #| --> (3 12) |#
cosimone has quit [Remote host closed the connection]
cosimone has joined #commonlisp
jmd_ has joined #commonlisp
jmdaemon has quit [Ping timeout: 252 seconds]
trocado has joined #commonlisp
mister_m has joined #commonlisp
Oddity has joined #commonlisp
aartaka has quit [Ping timeout: 268 seconds]
nij- has joined #commonlisp
<nij-> Can we hack the evaluating scheme of CL? For example, when evaluate a list that starts with a specific type of data (e.g. a keyword), can I make it do whatever I want (e.g. test if the first parameter is a plist, and get the corresponding field if so)?
thuna` has joined #commonlisp
tyson2 has joined #commonlisp
<Bike> nij-: No
<nij-> Oh no :( Why not? Isn't CL the #1=(programmable . #1#) language?
<White_Flame> you can write your own evaluator, or you can edit the existing implementation-specific editor
<White_Flame> you can shadow CL:DEFUN or CL:LAMBDA or use alternatives, and have it walk and transform the code for you
<nij-> ! Can I edit the existing evaluator in common lisp? Or should I go to the host lang?
<White_Flame> the host language is common lisp
<White_Flame> the "evaluator" is generally machine code generated by the lisp compiler written in lisp
<nij-> emm... sorry, I mean the language that's used to implement CL (what's the term?)
<White_Flame> CL is generally implemented in CL
<White_Flame> some runtimes have the garbage collector, early bootstrap, and OS interfacing written in C
<nij-> Got it, but in case it's not, say it's implemented in C..
<nij-> can I still hack the evaluator in CL?
<White_Flame> sure
<nij-> How ?!
<nij-> Within the language I mean.
<White_Flame> it's not standard common lisp, it's the implementations' own specific implementation
<White_Flame> you get into your implementation source code, and start changing it
<nij-> That's ok! When I hack the reader, the result isn't compliant either.
<nij-> Oh.. I have to get to the source code..
<White_Flame> it's much easier to do so in a simple interpreted lisp; the compiler adds a lot of complexity
<nij-> I cannot do in the target language (CL)?
<White_Flame> the source code is in common lisp
<White_Flame> the code of the compiler, that is
<nij-> I mean.. let's assume we have a CL implementation that's written in C (or any other lang)..
<White_Flame> it would be early passes of it where you would choose to transform things that are illegal by the standard, into legal expansions
<White_Flame> but you can do the exact same thing with your own custom DEFUN/LAMBDA/etc and a code-walking transformer
<White_Flame> or if you wrap your code in a macro
<White_Flame> having it be fully transparent means hacking the implementation
<aeth> just replace the reader
<aeth> if (:foo then do your regular logic, otherwise carry on. Of course, this is fragile, e.g. keyword:foo, ::foo, etc
<White_Flame> how would you do it at the reader level? only evaluated s-expressions would want the transformations, and the reader can't distinguish code from data yet
<nij-> White_Flame Yeah I am confused with the same question.
<White_Flame> nij-: try doing it with macros first
<White_Flame> then you know what transformation you want to do
<White_Flame> then get into the compiler or code walker of your implementation, and see where you can have it perform that transformation on all code
Guest563 has quit [Quit: WeeChat 3.6]
<White_Flame> there's nothing stopping you from redefining any lisp code in the lisp implementation
<nij-> I know that I can always hack the implementation itself.
<White_Flame> at runtime even
<nij-> But I mean, a reason that makes lisp "hackable" is that much hacking can happen within the target lang.
<nij-> It is host lang agnostic.
<White_Flame> but changing the definition of what's legal to evaluate means getting into the guts of it
<White_Flame> luckily, this is all in CL, as M-. traversable as any user code, and as re-definable as any user code. It's just lisp
MajorBiscuit has joined #commonlisp
<White_Flame> heck, years ago I redefined CL:EQUALP to respect string case
<nij-> I know it's changing the core/heart..
<nij-> The pythoners would also fringe upon the fact that we can change the reader in the target lang.
<White_Flame> I had to remove a package lock in SBCL, but that is just a function replacement from my user code early in loading my project
<White_Flame> so it's not even a permanent change to my on-disk lisp image; it only affects the language when my project is loaded
<Bike> this is why i summed it up with "no"
<nij-> Bike :D thanks
<White_Flame> it's 100% possible, 100% not legal, and somewhat% portable among the same implementation
<nij-> It's good to know a limitation of CL, even if it's not an issue in practice.
<White_Flame> dont' be afraid to hack it, that's how you learn the internals of the implementation, which gives you a broader understanding of what goes on in lisps
<Bike> as for why, i would sum that up by saying that having that capability would make compilation hard to impossible
<nij-> But I want to hack within the target lang..
<White_Flame> there is only 1 language
<White_Flame> (in this context)
<White_Flame> there's no separate language, or separate running instance, that has the compiler code; it's all in the same image
<White_Flame> mutate it to your heart's content. you can always restart from the unchanged reference code
<nij-> ?? Isn't some CL impl coded in C or something?
<White_Flame> embedded cl I think might have more C, but no reason it can't be as much CL in the compiler as any other lisp. THe target is just C instead of machine code
<White_Flame> I think there's some limitation that you're imagning that you're assuming, but simply isnt' there
<nij-> Hmm... I think I get some basic terminologies wrong.
<nij-> I assume that a CL implementation is implemented in a language X.
<White_Flame> I certainly don't know what your "target language" is implying here
azimut has quit [Remote host closed the connection]
<White_Flame> CL implementation is implemented in CL
<nij-> Assume that X is not CL. I want to hack CL as much as possible within CL.
<White_Flame> standard functions, libraries, compiler, internal support
MajorBiscuit has quit [Ping timeout: 252 seconds]
<White_Flame> if you cannot change the implementation (eg, if it's not written in CL), then you'll have to write things on top of it
<White_Flame> again, providing your own wrapper macros, shadowing lambda/defun/etc, and generating that which the foreign unchangeable compiler can grok
<nij-> White_Flame A compliant CL implementation must be implemented in CL?
azimut has joined #commonlisp
<White_Flame> and taht's what's so confusing, is that you're proposing a mostly non-existent scenario that's much harder to work with than just a standard CL written in CL
<White_Flame> no
<White_Flame> the implementation is not specified by the language
<White_Flame> but it's generally easiest to implement in CL, and it would be difficult to find a CL where the compiler is not written in CL
<nij-> I see. I'm asking a theoretical question.
<nij-> It's not really that I'm trying to finish a related project.
<nij-> So let's assume we're talking about a CL implemented in another lang.
<White_Flame> and then I believe the same answer holds: if for some reason you cannot change the implementation, you must work around it
<nij-> what is "it"?
<nij-> the implementation?
<White_Flame> the implemtation
<White_Flame> lisp environments grew up where it was "lisp all the way down"
<nij-> Can I work around it within the implementation?
<White_Flame> what do you mean by that?
<White_Flame> you're not "in" the implementation if it's foreign, non-lisp code, in terms of what your code affects
<White_Flame> or more specifically, regarding which code you can redefine
<nij-> hmm.. something like
<nij-> CL-USER> (setf *evaluator* my-evaluator)
<White_Flame> if CL:DEFUN, for instance, is not a lisp function, but a direct call to some C code at some fixed location, then you're not going to be redefining CL:DEFUN from within lisp. You can shadow it with your own package:DEFUN, though
<nij-> White_Flame That's ok.
<White_Flame> there is no standard interface for redefining the evaluator, it's an implementation detail
<nij-> oh..
<nij-> ok so Bike was right xD
<White_Flame> because it might be a compiler, it might be an interpreter, it might be a bytecode interpreter, and these have implications all over the place
<nij-> Bike thanks again
<White_Flame> well, that's not what you originally asked ;)
<nij-> :O ??
<nij-> Isn't it?
<White_Flame> but now that you've defined your terms better, yes if you cannot have access to the compiler's source code, you cannot change the compiler
<White_Flame> "Can we hack the evaluating scheme of CL"
<White_Flame> the answer is yes, for the vast majority of CLs. it is not standard, as I said up front
<nij-> I see.
<White_Flame> but "theoretically if the evaluator is not written in CL, and thus CL can't access it", then no, it cannot change it as it cannot access it
<White_Flame> *then no, CL cannot change the evalutor, as CL cannot access the evaluator
<nij-> got it
<nij-> it'd be cool if a lang can hack its evaluator within itself.
<White_Flame> it's pretty much the same situation as any other FFI code
<White_Flame> .....
<White_Flame> what do you mean? specifically? because you just undid the entire conversation
<White_Flame> you're talking about hacking a _foreign_ evaluator, in some unknown language, with unknown mechanism, from another language
<White_Flame> it's like saying "it'd be cool if CL could hack whatever microcode is running on whatever CPU it's running on"
<White_Flame> with no specific architecture, just "whatever"
<White_Flame> for every major instance of CL, the evaluator is written in CL and is as accessbile & hackable as any other user code
<nij-> I don't mind the major instance of CL. I mind CL as a language. And I apologize if I didn't express well enough.. I don't mean to undo the conversation.
<White_Flame> CL the language standard black-boxes the implementation, for good reason
<White_Flame> if it specified ways to change it, then implementations would be locked to the low-level evaluation assumptions of the 1980s
<nij-> why would it be locked?
<nij-> it can leave the *evaluator* unspecified
<nij-> but still force it to be exposed to the user
<White_Flame> because it has to be compatible to the changes specified in the standard
<nij-> ?
<White_Flame> and there are things similar to what you describe
<White_Flame> like the "environment" object passed into macroexpansion and such
<White_Flame> it's completely unspecified by the standard, and provided by the implementation
<nij-> yeah
<nij-> that's nice
<nij-> I'd think it's nice if *evaluator* can be exposed too.
<White_Flame> as such, the standard does not specify _anything_ about what's in the environment object, and you cannot change it without being non-portable
<White_Flame> there is no "evaluator" though
<nij-> ?!
<nij-> There's no evaluator?!
<White_Flame> compilers create machine code evaluators per executable body
<White_Flame> a singular evaluator object would be more comparable to an interpreter, because it would have to take s-expressions
<White_Flame> a compiler would have to do weird and expensive dispatching to cache compiled forms if it obeyed such an evaluator API
<nij-> Hmm.. are you saying what I been using is not a repl, but a rcpl (read-compile-print-lop)?
<White_Flame> eval in SBCL is (compile + execute)
<White_Flame> which of course is expensive cmpared to compile once and execute as many times as you want
<White_Flame> so if you have an "evaluator" object, which by the vocabulary lisp would take s-expressions, then jacking in a compiler would have impedance mismatch with the API's assumptions
<White_Flame> and this is a "lock-in" of overspecifying the implementation, as I was talking about above
<nij-> Can we expose the *compiler* instead?
<White_Flame> what would its interface be?
<Bike> there's a balance between exposing things to the user and overly constraining the implementation
<Bike> there used to be an *evalhook*, which you could bind to some function that would do evaluation
<White_Flame> and how much nonsense would it add to your workload if you were writing a simple interpreted CL?
<nij-> White_Flame interface?
<Bike> but that pretty much required lisp to do an interpreter in a way that's very constraining and slow
<Bike> nij-: the interface to the exposed compiler
<nij-> I still don't get what "interface" means here..
<White_Flame> nij-: interface = the set of functions, datastructure, & call ordering you need to make it owkr
<White_Flame> but I guess that's more "protocol" in local parlance
<Bike> i mean, what would you have exposed
<Bike> like what interface would you use to make this keyword whatever thing happened
<Bike> there are some existing hooks into the compilers, like macros. that has an interface via defmacro, macroexpand, bla bla
<Bike> into the compiler*
<White_Flame> the CL standard was written to allow implementations to make smart compilers, dumb compilers, interpreters, and support a whole host of variety of hardware as existed back then
<White_Flame> making an assumption that a compiler has to work like X and must have Y knobs to help implement your feature constrains the design of the implementation
<White_Flame> and prevents compilers from advancing, if they have to adhere to old protocols
<nij-> I don't intend to make more assumptions on the compiler, but less.
<nij-> The standard compiler can just stay as it is now.
<White_Flame> "the compiler has this hook/knob/etc" is assumptions about the design of the compiler
<nij-> But I'm thinking of a possibility for the user to hack it without going into the source.
<White_Flame> what's nice about (declare (optimize (speed..) (safety..) ..)) etc is that it doesn't mandate any specifics
<Bike> nij-: but the compiler would have to support some mechanism to let the user do that, is the point
<White_Flame> ahd thus compilers can be wildly different, they could JIT, they could do whatever, and the same options still apply
<White_Flame> nij-: hacking _is_ getting into the source. what you're talking about is configuration
<White_Flame> basically turning the spec into a dynamically editable language specification. Which is fine for research languages, and many do, but a spec must draw lines somewhere
<White_Flame> (at the extremes)
<nij-> (many do?)
<White_Flame> which ones?
<White_Flame> oh asking me? yeah, when creating a new language, many things are dynamically configured, until you decide what features you want to standardize on
<White_Flame> and then you can get a lot of holistic interactions between solidly designed components instead of everything having to interact with moving targets
<nij-> yeah.. I see
<White_Flame> stuff like this is asking for core lisp components to be a moving target
<nij-> it starts to make sense to me
<White_Flame> and that's not something languages include in their core, because then what do you design to?
<White_Flame> ok :)
<nij-> It's about the def of waht a lang is.
<Bike> more flexible lisps in this respect include maru, where eval is a generic function, and kernel, where you can define your own special operators
<White_Flame> but still, if you have a CL running in front of you, you can code in it, or hack the CL implementation itself to bend to your will & features ;)
<Bike> so you could look into those if you're interested, but they are, as white flame said, pretty much research languages rather than something usable for your program
<nij-> White_Flame But I don't want to create a whole new lang.
<White_Flame> the slightest change that you make to the CL evaluator would semantically make a whole new language
<nij-> I wish to be able to switch to another CL-package, and voila, the evaluator has now changed.
<nij-> White_Flame the user can decide if the change is small or big
<White_Flame> (well, the slighest _incompatible_ change you make...)
<nij-> Bike never heard of maru or kernel. THanks :)
<Bike> nij-: and, what, you'd write your own evaluator?
<nij-> Bike: never heard*
<Bike> in the other package?
<White_Flame> the best tool for DSLs or extending the lisp feature set is macros
<Bike> because you clearly have something you want to specify, it's not like it would be done for you
<nij-> Bike no I'm just thinking of a theoretical question: how flexible can a lang be?
<White_Flame> and again, you can shadow DEFUN/LAMBDA/etc in your own package and run through your own transforms, and keep it 100% portable CL
<White_Flame> to get the effect of it scoped to the current package
<Bike> well, let me give you a hypothetical example of how your extension could work
<Bike> say there was a generic function FUNCTION-LOOKUP, that took a function name and an environment, and looked up the name to return the function
<Bike> so (function-lookup 'car some-environment) => #'car
<nij-> mmhmmm
<White_Flame> we'll conveniently ignore the case of looking up FUNCTION-LOOKUP itself, right? ;)
<nij-> (mmhmmm=ok=agreeing)
<Bike> then you defined a method (defmethod function-lookup ((name keyword) env) (lambda (plist) (getf plist name)))
<Bike> so then (:foo a) evaluates to ((lambda (plist) (getf plist :foo)) a), which is i think what you had in mind
<Bike> so great
<nij-> Bike: In my specific example, yes.
<Bike> but then: how can the compiler function?
<Bike> the user could define whatever method on function-lookup at any time, so the compiler can't actually look up anything up ahead of time
<Bike> and so can't really do anything at all
<nij-> oh.
<nij-> hmm..
<Bike> this isn't the only possible interface, obviously, just the first one that popped into my head
<nij-> It seems that I was asking to have a compiler embedded in the lang already..
<Bike> but you see how it severely constrains the implementation to its detriment
<nij-> so the compiler also look up a sort of environment as well
<nij-> and decide how to compile
<nij-> something like that
<White_Flame> declarations, macroexpansions, etc, are all used by the compiler at the current state that they're set when the compiler is invoked
<White_Flame> if you change those things in the environment, the compiled code does not change to reflect them
<Bike> the metaobject protocol is a good example of the effort that goes into making some part of the language more flexible
<Bike> it lets you warp CLOS into a whole lot of different things, if you want. i've implemented something like python decorators using it, cl-json has self/javascript-style prototype programming
<White_Flame> and what is set at compile-time, and what is undefined consequence to change after it's been used, etc, is tackled a lot by the CL specification
<Bike> but they had to put a lot of thought into how the MOP interface would be designed, so that it isn't so free that the implementation has to do everything slowly
<Bike> and also so that users could use objects without having to fear that some extension would pull the carpet out from under them
<nij-> Hmm I think I now know why it's not reasonable:
<nij-> What I want is a way for the target lang to send a message to the host lang that changes stuff there.
<nij-> But this is.. not good, for some reason, I suppose.
<nij-> (I'm still not convinced why this isn't good though..)
<White_Flame> it's good for flexibility, it's bad for ecosystem & portability, it's bad for practical implications of speed & scale
<White_Flame> and again I think the optimization declarations in CL are a great example of sending a level of information to the compiler that is applicable for any architecture the implementation happens to use
<nij-> White_Flame that's a good summary!
<White_Flame> and thanks, Bike ;)
<nij-> thanks both :)
pve has quit [Quit: leaving]
ttree has joined #commonlisp
<jcowan> I think this is a complete list of the types that have representations in standard syntax (disregarding sharpsign-dot expressions): numbers, symbols, conses, strings, characters, simple vectors, and bit vectors. Am I missing anything?
<jcowan> Oh, general arrays and structs.
<Shinmera> arrays via #xA
<Shinmera> and I think random-state objects are required to be printable?
<Shinmera> er, print/readable.
<scymtym> pathnames
<aeth> keywords are kind of sort of different from symbols in that they're :foo instead of keyword:foo so you could include them on the list
<aeth> since you could view them as being of a subtype with its own representation in standard syntax
<aeth> plus, you don't need to quote them
<aeth> along those lines, you may want to consider complex numbers with the #C(...) syntax separate from the other numbers
<aeth> (which is a difference from Scheme, where they have a very number-y representation, not unlike the rationals)
Brucio-61 has quit [Read error: Connection reset by peer]
Brucio-61 has joined #commonlisp
<White_Flame> you'd also split up float vs int with that syntax-level distinction, but I don't think that's as meaningful to the list
<White_Flame> *I don't think any of these are that meaningful to the list
<White_Flame> and does #'foo another object, or just another use of cons
<White_Flame> (misedit, etc)
PoisonedPigeons has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
<seok> Anyone know whether zpb-ttf can return all character code points available in the ttf or I have to implement a loop looping through all code points with glyph-exists-p?
PoisonedPigeons has left #commonlisp [#commonlisp]
<Bike> jcowan: i think 22.1.3 is the part of the standard you'd want for a list
<jcowan> Okay, thanks, so pathnames are included. Random-states are readable/printable, but have no specific syntax.