phoe 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/>
mgl has quit [Ping timeout: 256 seconds]
dra has joined #commonlisp
<qhong> White_Flame: turns out that load-time-value completely doesn't work for me -- it nukes the lexical environment and break nesting :(
<White_Flame> well yeah, there's no lexical environment
<White_Flame> this is effectively toplevel, which is what you needed?
<White_Flame> I presume the expansion is something like `(lambda ,params (load-time-value (defun ,name ,params ,@body)) (,name ,@params))
<moon-child> qhong: s7 has first-class lexical environments, which are accessible at macroexpansion time. Just sayin
mixfix41 has joined #commonlisp
<moon-child> :)
<White_Flame> the whole point of the DEFUN is that it's separated from the lexical environment and replaceable
<White_Flame> where the PARAMS are the closed-over variable names
<White_Flame> hmm, no it would need more than that if the DEFUN needs to be able to write to those closures, too
<White_Flame> so it'd have to generate a (load-time-value (let (,closure-vars) (defun ,name ,lambda-params ...)))
<White_Flame> with a way of intializing them & passing them through on re-defun, which should all be possible
<qhong> moon-child: so does MIT Scheme, and is even installable/modifiable at runtime. Scheme >> CL!
<White_Flame> do both OUTER1 and INNER1 consider X to be closed over?
<qhong> White_Flame: Yes
<White_Flame> huh, well I would think it's just a plain bug, as you're manually constructing the lexical environment
<qhong> I think the problem is that there's a with-slots form by outer1 wrapping around inner1
<qhong> however, because all inner1 related code are inside ltv, the symbol macro bindings are discarded
<moon-child> qhong: in mit, can I say: ((if x - quote) 7)?
<moon-child> err, better example: ((if x - quote) y)
<qhong> moon-child: I can't read this
<White_Flame> ((if x '- 'quote) y) maybe?
<qhong> White_Flame: I tried with eval inside macroexpansion and it works but we know this doesn't work during compilation
<moon-child> White_Flame: nope
<moon-child> it says: evaluate x. If x is true, choose -. Otherwise choose quote. Apply whatever you chose to y
<moon-child> in other words: it is not even known until runtime whether y is evaluated
<qhong> oh i see, so you have F-expr
<moon-child> no not really fexpr
<qhong> what's the difference?
<moon-child> it's not different from (quote y). Special operators are just first class
<qhong> that sounds like saying special operators are just F-exprs
<qhong> Or is it different because you can't define your own F-expr?
<moon-child> (define (f x) x) ((f quote) a)
<moon-child> would you say that 'f' is an fexpr?
<qhong> f is a function, quote is an fexpr
<White_Flame> in other words, is the function-position expression required to be a plain function?
raeda has quit [Read error: Connection reset by peer]
<moon-child> qhong: ok
<qhong> White_Flame: what I get (they just have F-expr) is just that they have macros but at runtime
<sveit> does anyone know why SBCL issues a warning when a destructive function is applied to a macro argument?
<moon-child> sveit: because macro parameters are generally literal
<qhong> sveit: modifying literals
<moon-child> and literals may not be modified
<mfiano> sveit: Well it is undefined behavior
<opcode> I'm trying to query a postgres database and the query function requires you to do e.g. (query (:select '* :from 'schema.table)). Is there a way to construct the 'schema.table symbol programatically, i.e. by combining two variables?
<qhong> moon-child: But do you have *correct* (hygienic F-exprs)?
<White_Flame> sveit: a macro argument is literal source code, and modifying literals is undefined behavior
<moon-child> qhong: I am aware of no built-in mechanisms for enforcing hygiene
<qhong> moon-child: I assume you can define your own F-expr, then in most cases it also needs to capture call-site lexical environment to be useful
<qhong> moon-child: the beauty of hygienic F-expr is just that it is not through enforcement
<qhong> moon-child: eww macros
<moon-child> ¯\_(ツ)_/¯
<White_Flame> opcode: interning a string into a symbol?
<qhong> moon-child: so seems that s7 don't really have arbitrary F-exprs (which is hard to do right), just built-in special operators behave like F-exprs
<mfiano> opcode: alexandria:format-symbol or alexandria:symbolicate
<opcode> thanks, I'll try those
<opcode> also, are 'these 'things "objects"? in lisp parlance?
<qhong> moon-child: I also bet it runs hella slow, like any existing impl that have any flavor of F-expr
<qhong> F-expr hard to compile
<White_Flame> as in halting problem level of hard
<moon-child> it claims to be similarly similarly fast to guile
<moon-child> grep 'Speaking of speed' in docs page
<mfiano> opcode: something like (alexandria:format-symbol "~a.~a" scheme-var table-var) or (alexandria:symbolicate symbol-var '#:. table-var)
<Bike> compilation in general is halting problem level, so that's fine
<qhong> guile used to be hella slow as well until ppl stuff JIT in
<Bike> :v
<moon-child> er, no, lot faster than guile
<opcode> thanks mfiano
<moon-child> comparable to chicken, that was it
<White_Flame> symbolicate takes strings as well: (symbolicate 'schema "." 'table)
<mfiano> It does
<White_Flame> (but you have to be careful about case
<opcode> okay
<opcode> and (novice lisper here) those quoted literals
<opcode> 'these 'things
<mfiano> As for scheme, I think that is #lisp material
<opcode> are they "uninterned symbols"?
<White_Flame> no
<opcode> what are they called
<White_Flame> they're in the "current package" that the source code was read in
<mfiano> '#:foo is an uninterned symbol
<White_Flame> so by default, 'foo => CL-USER::FOO
<mfiano> a quoted one that is
<White_Flame> because that's the package you start in
<opcode> what do you call that syntax, quoting a symbol that hasn't been defined
<White_Flame> it's just quoting a symbol. Doesn't matter the nature of the symbol
<mfiano> quoting a symbol
<opcode> ok
<White_Flame> symbols are just names, used for many things
<opcode> yeah I just get tripped up on the nomenclature
<White_Flame> symbols name functions, symbols name lexical variables, whatever. A symbol isn't tied to any particular usage in defining something
<opcode> you read about plists so I thought :these :things were called properties
<mfiano> if it hasn't been defined yet, the Lisp Reader will "intern" it (put it in a lookup table for retrieving when seen again later)
<White_Flame> if you came from other compiled language, the first-classness of symbols can be a bit weird
<opcode> I cut my teeth on C++ in university in 2004, but most of my programming life has been in C# and Java
<White_Flame> yep
<White_Flame> their source code is not made of first-class symbols as lisp is
<mfiano> Yes, prepare to forget a lot, or tuck it away some place safe
<opcode> yeah it's a real paradigm shift
<White_Flame> also, I'd recommend #clschool, as this place can be full of esoterica
<opcode> cool
<White_Flame> in particular for asking learner questions
<mfiano> There is also #clschool if you want some more focused beginner help. Most people here may assume at least an intermediate level of CL
<White_Flame> feel free to lurk here, too :)
<opcode> should I take that to mean noob questions are off-topic here?
<mfiano> No they aren't
<opcode> ok
<opcode> I will still direct them to #clschool to avoid clutter as this is a busy channel at times
<opcode> thanks for the help
<mfiano> You might get some responses that are hard to digest, leading to a lot of recursive questions.
shka has quit [Ping timeout: 268 seconds]
<White_Flame> there's more of an assumption than you know more here
<White_Flame> hence answers can be extremely "complete" and obtuse
<mfiano> opcode: Good luck with your learning. I hope you are having fun
<mfiano> White_Flame: abtuse or obtuse?
<Bike> noob questions are fine but you run the risk of me explaining make-load-form until you start crying
<mfiano> err
igemnace has joined #commonlisp
wyrd has quit [Ping timeout: 276 seconds]
<mfiano> abstruse
<White_Flame> obtuse as in way wider than expected
wyrd has joined #commonlisp
<White_Flame> although yeah, probably crossed wires with abstruse
<mfiano> TIL that the two are often confused to the point that the former now has a dictionary definition for the latter.
<mfiano> Ignore me
dra has quit [Remote host closed the connection]
raeda has joined #commonlisp
waleee has quit [Ping timeout: 250 seconds]
karlosz has joined #commonlisp
waleee has joined #commonlisp
mixfix41 has quit [Ping timeout: 240 seconds]
karlosz has quit [Ping timeout: 256 seconds]
mixfix41 has joined #commonlisp
masinter has quit [Ping timeout: 240 seconds]
gaqwas has joined #commonlisp
unyu has quit [Quit: WeeChat 3.4]
parjanya has joined #commonlisp
<qhong> There's another issue in named-closure but idk if I should even attempt to solve it https://github.com/BlueFlo0d/named-closure/issues/1
<qhong> It's possible to simulate the "correct" environment sharing by indirection through a native closure, but this makes introspection and readble printing more complicated, moreover I think it nukes upgradability
<qhong> While it's not unreasonable to ask user to fix up old closures using STORE-VALUE, it sounds pretty impratical to expect user to fix the sharing structure between different closures. Thoughts?
unyu has joined #commonlisp
gaqwas has quit [Ping timeout: 256 seconds]
occ has quit [Remote host closed the connection]
asen has joined #commonlisp
morganw has quit [Remote host closed the connection]
s-liao has joined #commonlisp
<Bike> not sure you could have them share environments without having your own binding form instead of let. or using native closures, but then you can't access the environment later like i think you want to do.
<qhong> Bike: I know how to simulate. I just need to expand to basically a pair of (lambda () var) and (lambda (val) (setf var val)) in place, and use this pair of native closures as a "generalized variable".
<Bike> yeah i was thinking about that, but it seems like you'd lose read syntax?
<qhong> Bike: Given that I know all of my slots are storing such pairs, I can simply call the reader to print. And if *print-circle* = t, I can check the identity of the reader closure to reproduce the correct sharing
<qhong> My actual problem is about given I can simulate it, should I? The major downside I see is upgradability.
rotateq has left #commonlisp [ERC (IRC client for Emacs 27.2)]
<qhong> Is the `muffle-warning' restart ever implemented? http://clhs.lisp.se/Body/f_warn.htm
<qhong> Neither SBCL or CCL seem to have it. CL implementors DGAF about language standard???
<White_Flame> (let ,closure-vars (defun ,name ,params ,@body) (defun ,init-name ,param-vals ..(setf param param-val)..))
<semz> qhong: Do you have an example where it isn't working?
<White_Flame> hmm, maybe not. that would imply a singleton closure per name
<qhong> semz: (handler-case (warn "test") (warning (c) (print (list c (compute-restarts c)))))
<qhong> semz: and I don't see any `muffle-warning' restart
<semz> handler-case already unwinds beyond warn
<semz> you're looking for handler-bind
<qhong> semz: Hah, interesting, thanks!
<qhong> condition/restart much more confusing than call/cc
<semz> They take a bit of time to get used to.
varjag has joined #commonlisp
varjag has quit [Ping timeout: 240 seconds]
<Bike> call/cc is a primitive operator whereas the condition system is a whole system, so it can be easier to understand
waleee has quit [Ping timeout: 240 seconds]
Oladon has joined #commonlisp
Devon has quit [Ping timeout: 256 seconds]
myrrh has joined #commonlisp
igemnace has quit [Remote host closed the connection]
vats has quit [Ping timeout: 256 seconds]
terrorjack has quit [Quit: The Lounge - https://thelounge.chat]
terrorjack has joined #commonlisp
<|smlckz|> what are some synonyms for cdr?
<Bike> rest
<ns12> |smlckz|: What is the reason behind your question?
<ns12> Bike: Is CDR exactly the same as REST?
<|smlckz|> i am using first second third, so thought cdr would not look nice along with them
masinter has joined #commonlisp
<Bike> ns12: they do the same thing
<|smlckz|> hmm.. ''rest performs the same operation as cdr, but mnemonically complements first.''
<beach> Good morning everyone!
<ns12> Bike: In every case where cl:cdr appears, can it be substituted with cl:rest without change in functionality, and vice versa?
<ns12> Good morning beach.
<beach> ns12: Yes.
<beach> ns12: Also, the normal use of "substitute" is that if you "replace A by B", you "substitute B for A".
<beach> |smlckz|: FIRST, REST etc. are preferable if you are dealing with lists. CAR, CDR etc. are preferable if you are dealing with trees or with CONS cells as such.
<ns12> beach: Okay. Here's a corrected version: "In every case where cl:cdr appears, can it be replaced by cl:rest without change in functionality, and vice versa?"
<beach> Yes, again.
luis has quit [Quit: The Lounge - https://thelounge.chat]
<beach> Er, let me modify that....
<beach> (length (symbol-name 'cl:rest)) is not the same as (length (symbol-name 'cl:cdr)).
<beach> But when you use it as a function to call, they have the same functionality.
<pjb> |smlckz|: but note that NULL and ENDP don't do the same thing. If you use FIRST & REST you will probably want to use ENDP too.
<Bike> ns12: they have exactly the same effect. the differences are stylistic. and, technically, in (eql #'cdr #'cdr) you'd probably get true but in (eql #'cdr #'rest) you'd get false, but that's probably not the kind of difference you were thinking of.
luis has joined #commonlisp
<ns12> Bike: I was under the impression that CL:EQL should not be used on functions.
<beach> ns12: What gave you that impression?
<|smlckz|> so, non list argument to endp causes type-error
<beach> clhs eql
<Bike> it's a little big vague. that's why i said "probably". but i think every actual implementation will do (eql #'cdr #'cdr) => T.
<pjb> (eql (lambda ()) (lambda ()) ) #| --> nil |#
Colt has joined #commonlisp
<pjb> But: (defun foo ()) (eql (function foo) (function foo)) #| --> t |#
<pjb> ns12: so you can use it.
<beach> clhs endp
<ns12> So I can use it, but the results are implementation-dependent?
<pjb> Yes, they indicate how rest is implemented vs cdr.
<beach> |smlckz|: Yes, the standard says so: "Should signal an error of type type-error if list is not a list."
<pjb> (setf (fdefinition 'bar) (fdefinition 'foo)) (eql (function foo) (function bar)) #| --> t |#
<pjb> (defun baz ()) (eql (function foo) (function baz)) #| --> nil |#
asen has quit [Quit: Leaving]
<pjb> Another way is also: (function bar) #| --> #<Compiled-function foo #x302002FC69FF> |# but this could be corrected by the implementation in the printer.
<Bike> ns12: the only bit that's really vague is that you can't depend on closures produced by different evaluations being eq or not. something like #'eql should be fine regardless
<Bike> since you're not producing a closure
<mfiano> is there anything standard or in alexandria that will allow me to translate a list of lists of symbols to an alist: '((a b c) (1 2 3)) => '((a . 1) (b . 2) (c . 3)) ...or should I just write the simple code myself?
Oladon has quit [Quit: Leaving.]
<mfiano> list of list of atoms*
<pjb> (apply 'mapcar 'cons '((a b c) (1 2 3))) #| --> ((a . 1) (b . 2) (c . 3)) |#
<beach> (apply #'mapcar #'cons list)?
<mfiano> Yeah I know how to do it. Was just curious if this was provided in any of the two sources :)
<ns12> Is there a difference between (setf (fdefinition 'f) #'+) and (setf (symbol-function 'f) #'+) ?
<mfiano> Yes
<mfiano> The latter shouldn't be used
<Bike> they have the same effect, though.
masinter has quit [Quit: ~ Trillian - www.trillian.im ~]
<ns12> Ah, why should the latter be avoided?
<Bike> symbol-function is just fdefinition that works on less stuff.
<Bike> since it only handles symbols, whereas fdefinition can do symbols and also (setf whatever).
<beach> ns12: It is a leftover from when function names could only be symbols.
wheelsucker has quit [Remote host closed the connection]
wheelsucker has joined #commonlisp
<mfiano> ns12: Symbols are objects with different cells that can be retrieved or modified. But a function can be named by a list of 2 specific symbols as well.
<beach> Though, of course SICL symbols have only two cells, namely one for the name and one for the package.
<beach> I guess "slots" would have been a better term.
<ns12> mfiano: Could you give an example? I don't quite understand what you mean by "a function can be named by a list of 2 specific symbols as well".
<beach> ns12: Bike told you. (defun (setf foo) (x y) ...)
<Bike> (setf foo) can be a function name
<ns12> Oh I see, this is a special case for SETF.
<mfiano> In that case, the actual name of the function is (setf foo), which a reference to the function object can be obtained with (function (setf foo)) or simply #'(setf foo)
myrrh has quit [Quit: leaving]
<beach> I wish the standard hadn't mentioned "cells" like function cells and value cells.
<beach> They are historical implementation details.
<mfiano> ns12: No this is a special case for what is permitted to be a function name
<ns12> mfiano: For (setf foo), #'fdefinition would work but #'symbol-function would not, which is why #'fdefinition is preferred. Is my understanding correct?
<mfiano> It has not much to do with SETF. Infact your (setf foo) function doesn't even have to "set" anything.
<mfiano> ns12: Yes
<ns12> mfiano: Bike: beach: Thank you for the explanations.
<Bike> no problemo
<mfiano> Anytime
<beach> ns12: Try (macroexpand '(setf (unknown-stuff x) 234)) and you will see the use of a function such as (SETF ...) It is what SETF expands to when given an unknown operator.
<mfiano> Common Lisp isn't functional, but the standard and CDR's prefer acretion over mutability :)
<mfiano> *accretion
Guest23 has joined #commonlisp
<mfiano> I'll take hysterical raisins any day, which some actually even come in useful at times, over the Python2/Python3 disaster, or anything inbetween.
<light> Hi, I'm reading Practical Common Lisp and following along using SBCL. I'm getting unwanted new lines inserted before the y-or-n-p prompts in my code. What exactly causes this and how do I fix it? http://paste.debian.net/1228078/
Guest23 has quit [Quit: Client closed]
<beach> light: It is probably that the same stream is used for several things.
wmblathers has quit [Quit: Ping timeout (120 seconds)]
<beach> light: I wouldn't count on detailed behavior like that for the REPL. It might be well defined, but I don't know the details.
<mfiano> There is also some ambiguities in the standard
<light> Hm
<mfiano> It is intended that the reply require the user to take more action than just a single keystroke, such as typing the full word yes or no followed by a newline. It does not say how that should be written to the stream.
<mfiano> SBCL inserts a newline when enter is pressed. CCL does not.
<beach> clhs y-or-n-p
<beach> clhs yes-or-no-p
tyson2 has quit [Remote host closed the connection]
semz_ has joined #commonlisp
<light> So y-or-n-p is using fresh-line to output a new line because it can't determine if it's already at the start of the line.
semz has quit [Ping timeout: 250 seconds]
<beach> Maybe so.
jstoddard has quit [Quit: Leaving]
igemnace has joined #commonlisp
<|smlckz|> given a function or lambda, is there a way to know how many (mandatory) arguments it takes?
semz_ is now known as semz
<ns12> |smlckz|: Interactively or programatically?
<|smlckz|> programmatically
<beach> |smlckz|: There is no such thing as "a lambda". There is a "lambda expression" that, when evaluated, becomes a function. And the term is "required arguments". The only function that can answer that is FUNCTION-LAMBDA-EXPRESSION but there is no guarantee that it will.
<beach> ns12: Why does it matter?
<beach> |smlckz|: For generic functions, it is possible...
<beach> mop generic-function-lambda-list
<beach> But you need the MOP.
<|smlckz|> hmm
<|smlckz|> now i remembered a good word instead of number-of-variables.. arity !
<qhong> |smlckz|: there's also plenty of compatibility layers that just give you arglist
<qhong> I think I mentioned it just earlier today, either `swank' or `trivial-arguments' will do
<qhong> MIT Scheme has procedure-arity btw
<Bike> implementations may not store the information, though. for example at space 3.
[w] has joined #commonlisp
<mfiano> That macro I've been writing for two days _was_ finished, but I just found one particular call site it doesn't know how to handle. I'm not quite sure how to handle late binding with this...
s-liao has quit [Quit: Client closed]
<|smlckz|> two days?
<mfiano> Yes, I am slow, and just getting back into programming.
<ns12> beach: "Why does it matter?" - #'describe prints the argument list.
<mfiano> Here is what I'm up against. Test case 5 needs to be handled. That is, body forms may include references to previous bindings, and I am not sure how to know how to order the LET bindings correctly to account for that, or if that is even possible: https://gist.github.com/mfiano/3437b61317dd0c81710d77e3be29ea70#file-utils-lisp-L98
<qhong> mfiano: why you ever need to SUBLIS? Why not just wrap your BODY with `(let (bindings) ,@body)?
<mfiano> Because I need to substitute the user-supplied variables with the proper gensym'd parameters of the generated m-v-c function.
vats has joined #commonlisp
<qhong> Why you need to subsitute? `(let ((old-variable new-variable)) ,@body)?
<qhong> Also I'm not sure why you need to gensym at all. You need gensym if you're creating new variables. Now user always supply bunch of symbols and you can use them just fine
<qhong> always -> already
<mfiano> Because old variables do not need to be unique across bindings.
<mfiano> That is the whole point of the macro
Jing has joined #commonlisp
<beach> ns12: I see what you mean. Still DESCRIBE is not required to show that information, and as Bike pointed out, the information may not be available.
<|smlckz|> hmm, so passing arity along with the function is the way to go for now.. until i use objects or such..
igemnace has quit [Quit: WeeChat 3.4]
<beach> You are already using objects.
Bike has quit [Quit: Connection closed]
akoana has joined #commonlisp
s-liao has joined #commonlisp
<qhong> mfiano: I see your problem. I'm still pretty sure SUBLIS is unnecessary, but the bigger problem is that your syntax doesn't seem well defined. In your test case 5, what if there are 5 channel in total and someone write spec=((rgb 3) (a 2))? What will the `a's in your first form refer to?
<mfiano> If you look at the macro definition, you can see in the spec normalization that it is guaranteed to be at most 4.
myrrh has joined #commonlisp
<mfiano> I don't think you understand the full utility of the macro though. And I am too tired and about to go to sleep to fully explain it, so don't worry.
aartaka has joined #commonlisp
<qhong> mfiano: I see it, but I'm saying it's just a coincidence. A good syntax should work for any number channel. Also even just for 4 channels, what if someone write spec=((a 2) (b 2)) and do forms=(* a b) (+ a b)?
varoun has joined #commonlisp
<ns12> |smlckz|: Try this library: https://github.com/Shinmera/trivial-arguments
s-liao has quit [Ping timeout: 256 seconds]
varoun has quit [Ping timeout: 240 seconds]
s-liao has joined #commonlisp
igemnace has joined #commonlisp
mgl has joined #commonlisp
[smlckz] has joined #commonlisp
aartaka has quit [Ping timeout: 240 seconds]
aartaka has joined #commonlisp
lisp123 has joined #commonlisp
igemnace has quit [Quit: WeeChat 3.4]
iamFIREc1 has quit [Ping timeout: 250 seconds]