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]
s-liao has quit [Ping timeout: 256 seconds]
lisp123 has quit [Remote host closed the connection]
<pjb> |smlckz|: sometimes you can use function-lambda-expression, but implementations can drop the info, so you often just get NIL.
rudi has quit [Quit: You have been kicked for being idle]
<pjb> |smlckz|: otherwise, a lot of implementation provide an implementation specific API to get it. You can use swank as a portability layer: (swank/backend:arglist (function sin)) #| --> (ccl::x) |#
iamFIREcracker has joined #commonlisp
pve has joined #commonlisp
lisp123 has joined #commonlisp
rogersm has quit [Read error: Connection reset by peer]
<pjb> mfiano: so for a specs of (a 1) you would want to expand to a (let ((a <something>)) …) but for a specs of (rgb 3) you would want to expand to (let ((#:arg1 <something>) (#:arg2 <something>) (#:arg3 <something>)) …) ???
lisp123 has quit [Ping timeout: 240 seconds]
gaqwas has joined #commonlisp
shka has joined #commonlisp
gaqwas has quit [Remote host closed the connection]
rogersm has joined #commonlisp
<mgl> |smlckz|: yes, swank-backend is pretty good
<EdLangley[m]> Just used swank to get nicer "eldoc" in lispworks :)
<EdLangley[m]> Just a hack, so lots of ::
rain3 has joined #commonlisp
Algernon69 has joined #commonlisp
cosimone has joined #commonlisp
amb007 has quit [Ping timeout: 250 seconds]
amb007 has joined #commonlisp
Algernon69 has quit [Ping timeout: 256 seconds]
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
vats has quit [Ping timeout: 256 seconds]
cosimone has quit [Remote host closed the connection]
Nilby has joined #commonlisp
VincentVega has joined #commonlisp
Lord_of_Life has quit [Ping timeout: 250 seconds]
Lord_of_Life_ has joined #commonlisp
Lord_of_Life_ is now known as Lord_of_Life
cage has joined #commonlisp
amb007 has quit [Ping timeout: 256 seconds]
amb007 has joined #commonlisp
srji has quit [Quit: leaving]
varjag has joined #commonlisp
molson__ has quit [Ping timeout: 250 seconds]
[w] has quit [Quit: zzz]
bonmlp has joined #commonlisp
Dynom has joined #commonlisp
lisp123 has joined #commonlisp
occ has joined #commonlisp
lisp123 has quit [Ping timeout: 240 seconds]
vats has joined #commonlisp
attila_lendvai has joined #commonlisp
Devon has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
tyson2 has joined #commonlisp
lisp123w has joined #commonlisp
random-nick has joined #commonlisp
<lisp123w> I am thinking of writing some 'portable' code (specifically code that can work with both CLIM & CAPI), so at some point I need to access implementation specific functions
<lisp123w> So my plan is to define the basic operations in terms of generic functions that take in an optional value, and then have the methods implement for each specific implementation
cosimone has joined #commonlisp
<lisp123w> Is there a particular way I should approach this?
<lisp123w> Right now, I can only think of having to have two functions, something like this: (defvar *impl* :clim) (defun insert-string-at-point (string) (%insert-string-at-point string *impl*)) .. (defgeneric %insert-string-at-point (string impl))
<beach> lisp123w: Check out our libraries Eclector, Cluster, Trucler, etc. They all use a CLIENT required parameter that can handle that situation.
<lisp123w> beach: Thank you!
<lisp123w> I will do that now
<beach> This technique has turned out to be extremely flexible.
<pjb> lisp123w: or: (defmethod foo (arg &optional (*impl* *impl*)) …)
cosimone has quit [Remote host closed the connection]
<lisp123w> pjb: I was thinking that, but if I remember, can't dispatch on optionals?
<phoe> it isn't an optional parameter
<phoe> (defgeneric foo-with-client (client ...)) (defun foo (...) (foo-with-client *default-client* ...))
<beach> Yes, we do that in Eclector for instance, where we can't alter the signature of READ.
mingus has joined #commonlisp
<phoe> where *default-client* is both something you provide and something that the clients of your library can rebind themselves as a dynavar
<lisp123w> phoe: Yeah I was thinking just that
<beach> So for Eclector, we can do (let ((eclector:*client* *sicl*)) (eclector:read...))
<lisp123w> I see
<beach> In our case, the default methods provided by the library do not specialize to the CLIENT parameter, but the same client code that binds *client* can provide extending or overriding methods that specialize to the class of their particular client.
<beach> Like (defmethod eclector:interpret-token ((client sicl) ...) ...)
<lisp123w> That's an interesting idea
<lisp123w> Very interesting actually
<beach> We are very pleased with this "discovery". It allows for code for multiple clients to coexist in the same Common Lisp image.
<Nilby> and to make it look nice, you can (defmacro foo (..) (foo-with-client *default-client* ...))
<beach> Well, in the case of Eclector, READ is defined to be a function, so it can't be a macro.
<phoe> Nilby: that'll badly break #'foo
<lisp123w> beach: Is there a reason for the local binding (let ((client *client*))...) in particular?
<phoe> lisp123w: where do you mean?
<lisp123w> I am just looking at (defun read-aux ...) in read.lisp in Eclector
<beach> Let me look at it...
<lisp123w> I would have done it as &optional (client *client*), but maybe there's a particular reason (from what I understand they should be the same)
<lisp123w> (well not actually the same, but the effect being the same if client is not supplied in as an optional)
<phoe> it's surely a way to de-dynamify the binding, because CLIENT is a lexical variable
<beach> lisp123w: It is a bit more expensive to access a dynamic variable than a lexical one.
<phoe> which kind of makes sense because you only need the dynamic binding on the boundary of your system, so you can effectively pass extra function arguments this way
<lisp123w> beach: Got it! Thanks (thakns phoe too)
<phoe> so what beach said + you guard your code against some funky re-binding that can cause one part of your code to be executed with one client and another part with another
vats has quit [Ping timeout: 240 seconds]
<beach> Yes, you send a message to the person reading your code that you intend to use the same value of *client* in the entire function.
<phoe> that's what you get when the client object becomes bound to a lexical variable instead of being accessed by a dynavar
<lisp123w> phoe: Thanks, is that mostly an issue in multiple processes?
<phoe> not really
<phoe> every thread has its own set of dynamic bindings, so that isn't a problem
<lisp123w> Ah so it is just taking a 'snapshot' of its value at that point in time?
<phoe> yes
mingus has quit [Quit: Lost terminal]
<phoe> that's what I mean by de-dynamifying
<lisp123w> Got it, thanks!
<beach> lisp123w: Imagine you had (foo *client*) (bar) (baz *client*).
<beach> You don't know whether BAR might do (setf *client* ...).
<phoe> you cannot make a closure over a dynamic variable because it's too dynamic to be closed over™
<lisp123w> beach: Nice example, I never really thought of this point until now
<phoe> you need to grab the value and stuff it into a lexical variable which is less prone to dynamism such as random-seeming changes
<phoe> which is what happens here
<beach> It is not a big deal usually, and in read-aux I don't think this case can happen.
<lisp123w> I see. Still a good practice to follow where relevant
<beach> Indeed.
<beach> lisp123w: Eclector is a great library to study, for many reasons.
<lisp123w> beach: Thanks for the heads up, will do! I'm now at the stage where I'm trying to learn from other code vs. learning the concepts
<phantomics> Looking for people's opinions on an engineering issue that's come up
<beach> lisp123w: That's excellent!
<lisp123w> Which Lisp makes it possible since its so open and easy to introspect :)
<beach> Sure.
notzmv has quit [Ping timeout: 268 seconds]
<phantomics> In April, you can pass values into an April code invocation from outside. That includes arrays, naturally. APL isn't strongly typed so you can pass in an array, assign an element of an incompatible type, and April will automatically create a copy of the array with a compatible type to assign the new value into
gaqwas has joined #commonlisp
<phantomics> The problem is this: If you pass in an outside array and assign a compatible value into it, the array you passed in will be destructively changed
<phantomics> But if you assign an incompatible value, the outside array will not be changed because April silently made a copy. This is confusing for some people
<phantomics> There's an example here: http://ix.io/3N7N
<phantomics> This code has a side effect, changing the "a" array that was passed in
<sm2n> That seems fine to me? Just have to specify that April takes ownership of arrays passed in, and if you want the old one, make a copy
<phantomics> But if that array is of a type incompatible with the 20 value, like (unsigned-byte 4), then the original array would be copied and the side effect would not occur. Confusing, obviously. What do you think is the best approach here? Always copy arrays passed in so that side effects don't occur?
<phantomics> sm2n: The issue is with inconsistency, the original array could either be changed or not changed depending on what you're assigning into it, which can throw people for a loop
notzmv has joined #commonlisp
<phoe> make it configurable from the outside perhaps
<phoe> let the user pass a dynavar that specifies the behavior: always copy an array/prevent all side effects, versus copy only when necessary due to array specializations, versus never copy and signal an error instead
<phoe> s/pass/rebind/
<phantomics> I could just warn users "don't count on April destructively changing arrays unless you know your array's type and exactly how assignment works, otherwise pass the value back out of April explicitly"
<sm2n> I don't think a dynavar is a good idea
<sm2n> because then you can't rely on a default
<phoe> I mean, I think I can find use cases for the two "extreme" behaviors here - one is extreme side effect avoidance, useful for functional programming, one is extreme performance and a situation where the user *wants* to be notified of type errors because they want to fix them
<phoe> sm2n: why not? make the dynavar have a default value, e.g. the current April behavior
<phantomics> A more simple "configuration" would just be for users to use alexandria's copy-array on anything they want to pass in with no possible side effects
<phantomics> I can't have type errors, APL is typeless so adding type errors would require extensive rethinking of the entire language, k is typed and has many lexical features dedicated to managing those types in contrast to APL
<sm2n> Consider the case where you are using April and you have a library using April, every invocation in the library will have to rebind the config var if it relies on that behavior being consistent, because you could change it globally
<phantomics> sm2n: correct, the dynvar approach has portability pitfalls
<phoe> yep, I see
<phoe> an explicit copy-array would then work I guess
<sm2n> Yeah, I think that makes sense
s-liao has joined #commonlisp
<phantomics> That sounds reasonable, I'll just add a bit of documentation basically warning "If you assign values to an array passed into April from outside, make sure you know what you're doing as it may or may not have side effects."
<phoe> "april is allowed to be destructive on the arrays it receives"
<phoe> not unlike CL:SORT and friends
morganw has joined #commonlisp
cosimone has joined #commonlisp
bonmlp has quit [Ping timeout: 256 seconds]
gaqwas has quit [Remote host closed the connection]
nij- has joined #commonlisp
lispy has joined #commonlisp
lispy has quit [Remote host closed the connection]
lispy has joined #commonlisp
karmichammer has quit [Ping timeout: 240 seconds]
shka has quit [Read error: Connection reset by peer]
shka has joined #commonlisp
karmichammer has joined #commonlisp
lispy has quit [Remote host closed the connection]
lispy has joined #commonlisp
karmichammer has quit [Ping timeout: 250 seconds]
cosimone has quit [Read error: Connection reset by peer]
cosimone has joined #commonlisp
lispy has quit [Quit: Leaving]
lisp123 has joined #commonlisp
parjanya has quit [Ping timeout: 256 seconds]
lisp123 has quit [Ping timeout: 256 seconds]
psf has quit [Ping timeout: 240 seconds]
wmblathers has joined #commonlisp
wmblathers has quit [Client Quit]
psf has joined #commonlisp
karmichammer has joined #commonlisp
Algernon69 has joined #commonlisp
attila_lendvai_ has joined #commonlisp
attila_lendvai has quit [Ping timeout: 268 seconds]
wyrd has quit [Ping timeout: 276 seconds]
karmichammer has quit [Ping timeout: 250 seconds]
wyrd has joined #commonlisp
Algernon69 has quit [Ping timeout: 268 seconds]
domovod has joined #commonlisp
epony has quit [Quit: QUIT]
vats has joined #commonlisp
lisp123 has joined #commonlisp
dra has joined #commonlisp
<lisp123> pjb: Do you remember what your lambda list parser was called? Trying to find it now as its v. useful for macro writing
Bike has joined #commonlisp
<phoe> lisp123: for what kind of lambda lists?
<phoe> alexandria:parse-ordinary-lambda-list is for ordinary ones, can't say anything about others though
<lisp123> phoe: Just being able to split (required &optional &rest etc.)
<lisp123> Oh thanks, I'll check that out too
nij- has quit [Ping timeout: 250 seconds]
tyson2 has quit [Ping timeout: 256 seconds]
tyson2 has joined #commonlisp
kevingal has joined #commonlisp
ec has joined #commonlisp
mixfix41 has quit [Ping timeout: 250 seconds]
karmichammer has joined #commonlisp
Algernon69 has joined #commonlisp
epony has joined #commonlisp
Algernon91 has joined #commonlisp
Algernon69 has quit [Ping timeout: 268 seconds]
<jmercouris> lisp123: I think it is cesareum or something
<jmercouris> The string isn’t coming to mind exactly
wyrd has quit [Ping timeout: 276 seconds]
wyrd has joined #commonlisp
<lisp123> jmercouris: Thanks! Yeah that must be it
kevingal has quit [Ping timeout: 268 seconds]
<jmercouris> lisp123: if you want an example, we use Alexandria in the Nyxt codebase to split lambda lists
<lisp123> jmercouris: Nice one, I will check it out
<lisp123> jmercouris: Thanks
s-liao has quit [Quit: Client closed]
ec has quit [Ping timeout: 276 seconds]
lisp123_ has joined #commonlisp
lisp123_ has quit [Read error: Connection reset by peer]
lisp123 has quit [Ping timeout: 256 seconds]
nij- has joined #commonlisp
Jing has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<pjb> lisp123w: com.informatimago.common-lisp.lisp-sexp.source-form:parse-lambda-list
<pjb> it's easy: just load com.informatimago in your rc file, and then you can (apropos "whatever").
mixfix41 has joined #commonlisp
igemnace has joined #commonlisp
wmblathers has joined #commonlisp
aartaka has quit [Ping timeout: 250 seconds]
aartaka has joined #commonlisp
parjanya has joined #commonlisp
nij- has left #commonlisp [#commonlisp]
Algernon666 has joined #commonlisp
Algernon91 has quit [Ping timeout: 268 seconds]
nij- has joined #commonlisp
domovod has quit [Quit: WeeChat 3.4]
Algernon91 has joined #commonlisp
Algernon666 has quit [Ping timeout: 268 seconds]
nij- has quit [Ping timeout: 250 seconds]
rogersm has quit [Quit: Leaving...]
lispy has joined #commonlisp
d4ryus has quit [Quit: WeeChat 3.4]
vats has quit [Remote host closed the connection]
Algernon91 has quit [Read error: Connection reset by peer]
Algernon91 has joined #commonlisp
d4ryus has joined #commonlisp
kevingal has joined #commonlisp
varjag has quit [Ping timeout: 240 seconds]
treflip has joined #commonlisp
mixfix41 has quit [Ping timeout: 250 seconds]
tyson2 has quit [Remote host closed the connection]
waleee has joined #commonlisp
kevingal_ has joined #commonlisp
lispy has quit [Quit: Leaving]
lispy has joined #commonlisp
rogersm has joined #commonlisp
myrrh has quit [Ping timeout: 250 seconds]
cosimone has quit [Remote host closed the connection]
cosimone has joined #commonlisp
mixfix41 has joined #commonlisp
varjag has joined #commonlisp
amb007 has quit [Ping timeout: 250 seconds]
amb007 has joined #commonlisp
ChanServ has quit [shutting down]
treflip has quit [Quit: good night]
ChanServ has joined #commonlisp
lispy has quit [Quit: Leaving]
lispy has joined #commonlisp
aartaka has quit [Ping timeout: 240 seconds]
Algernon666 has joined #commonlisp
Devon has quit [Ping timeout: 240 seconds]
Algernon91 has quit [Ping timeout: 268 seconds]
lispy has quit [Quit: Leaving]
wheelsucker has quit [Read error: Connection reset by peer]
wheelsucker has joined #commonlisp
perrierjouet has quit [Remote host closed the connection]
perrierjouet has joined #commonlisp
tyson2 has joined #commonlisp
dra has quit [Remote host closed the connection]
xaltsc has joined #commonlisp
amb007 has quit [Ping timeout: 256 seconds]
amb007 has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
masinter has joined #commonlisp
masinter has left #commonlisp [#commonlisp]
rain3 has quit [Remote host closed the connection]
rain3 has joined #commonlisp
Algernon666 has quit [Ping timeout: 268 seconds]
rogersm has quit [Quit: Leaving...]
attila_lendvai_ is now known as attila_lendvai
huckleberry has joined #commonlisp
<huckleberry> I've been using closures as pseudo-streams (basically generators) in a lot of projects instead of separate state objects. I haven't really noticed an issue with speed but should I be doing that or should I be using separate state objects i.e. gray streams?
Masinterlisp has joined #commonlisp
<mfiano> Gray streams/generic functions allow for flexibility and extensibility.
<mfiano> I would much prefer them over a closure that is hard to debug/poke at from the outside
<huckleberry> all right, thanks
rain3 has quit [Ping timeout: 268 seconds]
Masinterlisp has left #commonlisp [#commonlisp]
Masinterlisp has joined #commonlisp
Grauwolf has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
mon_aaraj has joined #commonlisp
shka has quit [Quit: Konversation terminated!]
cage has quit [Quit: rcirc on GNU Emacs 27.1]
shka has joined #commonlisp
huckleberry has quit [Quit: disconnected]
notzmv has quit [Ping timeout: 268 seconds]
kevingal_ has quit [Remote host closed the connection]
kevingal has quit [Remote host closed the connection]
mon_aaraj has quit [Ping timeout: 240 seconds]
mon_aaraj has joined #commonlisp
Dynom has quit [Quit: WeeChat 3.4]
shka has quit [Ping timeout: 256 seconds]
hobo has joined #commonlisp
Algernon69 has joined #commonlisp
Algernon91 has joined #commonlisp
perrierjouet has quit [Quit: WeeChat 3.4]
Algernon69 has quit [Ping timeout: 268 seconds]
perrierjouet has joined #commonlisp
m5zs7k has joined #commonlisp
epolanski has quit [Quit: Connection closed for inactivity]
amb007 has quit [Ping timeout: 240 seconds]
lispy has joined #commonlisp
<lispy> (format t "Hello")
Masinterlisp has quit [Quit: ~ Trillian - www.trillian.im ~]
masinter has joined #commonlisp
cosimone has quit [Ping timeout: 250 seconds]
Algernon91 has quit [Ping timeout: 268 seconds]
VincentVega has quit [Quit: ERC (IRC client for Emacs 27.2)]
<White_Flame> (terpri)
<phoe> (princ "CL-USER> ")
attila_lendvai has quit [Ping timeout: 240 seconds]
<EdLangley[m]> (eval (capi:prompt-for-form "CL-USER>"))
varjag has quit [Quit: ERC 5.4.1 (IRC client for GNU Emacs 29.0.50)]
occ has quit [Ping timeout: 250 seconds]
tyson2 has joined #commonlisp
<dre> (foo bar ())
<dre> god I love lisp
pve has quit [Quit: leaving]
<bollu> Oh neat, "Gray" is after the person who invented the CLOS spec for how streams "should" be?
pillton has joined #commonlisp
amb007 has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
notzmv has joined #commonlisp
<moon-child> I thought it was 'gray' as in 'gray water'
<sm2n> gray as in "David Gray"
dra has joined #commonlisp
mgl has quit [Ping timeout: 256 seconds]
karmichammer has quit [Ping timeout: 240 seconds]
<dbotton> Xach when is the next quicklisp release coming up?