judson_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
mbomba has joined #lisp
judson_ has joined #lisp
thijso has quit [Ping timeout: 256 seconds]
thijso has joined #lisp
johnjay has joined #lisp
epony has quit [Quit: reconfigure]
epony has joined #lisp
bitmapper has quit [Quit: Connection closed for inactivity]
gko_ has joined #lisp
gko_ has quit [Ping timeout: 264 seconds]
judson_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
judson_ has joined #lisp
trittweiler has quit [Ping timeout: 265 seconds]
trittweiler has joined #lisp
notzmv has quit [Remote host closed the connection]
rumbler31 has quit [Remote host closed the connection]
rumbler31 has joined #lisp
notzmv has joined #lisp
iyzana[m] has joined #lisp
iyzana[m] has left #lisp [#lisp]
iyzana[m] has joined #lisp
iyzana[m] has left #lisp [#lisp]
wxie has joined #lisp
andreyorst has quit [Remote host closed the connection]
cods has quit [Ping timeout: 240 seconds]
cods has joined #lisp
<lotuseater>
Xach: i recently learned about the circle-ellipse problem and how it can be solved using CLOS with change-class and update-instance-for-redefined-class. advanced features for nontrivial problems :)
<ebrasca>
phoe: Hi
<phoe>
ebrasca: hey
<ebrasca>
phoe: I don't know how to help with Hexstream problem.
<phoe>
ebrasca: you don't need to.
<phoe>
I guess that you know shit has hit the fan when Ron Garret of NASA JPL fame decides to step in and settle some things straight.
<phoe>
;; and I won't say any more here because I'm scared of jackdaniel even when he's most likely sleeping
<curiouscain>
I didn't know it was /that/ Ron Garrett
igemnace has quit [Remote host closed the connection]
galex-713 has quit [Ping timeout: 272 seconds]
ebrasca has quit [Remote host closed the connection]
<mfiano>
I use change-class quite a bit, and the foundation of my game engine depends on it actually.
mbomba has quit [Quit: WeeChat 3.0]
EvW has quit [Ping timeout: 258 seconds]
akoana has quit [Quit: leaving]
Lord_of_Life_ has joined #lisp
Lord_of_Life has quit [Ping timeout: 240 seconds]
wxie has quit [Remote host closed the connection]
beach has quit [Ping timeout: 264 seconds]
ldbeth has joined #lisp
notzmv` has joined #lisp
notzmv has quit [Ping timeout: 256 seconds]
notzmv` has quit [Remote host closed the connection]
<ldbeth>
good morning
surabax has quit [Quit: Leaving]
orivej has quit [Ping timeout: 240 seconds]
tempest_nox has quit [Read error: Connection reset by peer]
<ldbeth>
I'm looking for a compact data type for int * char -> int lookup
<ldbeth>
currently I take an array of hashtables
gaze__ has quit [Ping timeout: 260 seconds]
mjl has quit [Ping timeout: 260 seconds]
mjl has joined #lisp
gaze__ has joined #lisp
buoy49 has quit [Read error: Connection reset by peer]
jerme_ has quit [Ping timeout: 264 seconds]
banjiewen_ has quit [Read error: Connection reset by peer]
alanz has quit [Read error: Connection reset by peer]
kilimanjaro has quit [Read error: Connection reset by peer]
kilimanjaro has joined #lisp
banjiewen_ has joined #lisp
tempest_nox has quit [Read error: Connection reset by peer]
alanz has joined #lisp
jerme_ has joined #lisp
buoy49 has joined #lisp
<beach>
ldbeth: That will work only if the domain of n is compact.
<beach>
If it is not compact, a hash table of hash tables might be better.
<beach>
But this is a typical case where exploiting the properties of the domain can improve performance a lot.
<beach>
Like whether the domains are compact, small in size, etc.
<beach>
Also, another property to exploit might be the frequency of the modification of the mapping.
<beach>
As in, do you mostly query it and only rarely modify it?
Misha_B has quit [Read error: No route to host]
malm has quit [Quit: Bye bye]
Bike has quit [Quit: Lost terminal]
<ldbeth>
beach: yes. the integer domain is continous (from 0 to n), and charactor is limited to 245 ascii code
<edgar-rft>
easye: the CONSequences are unspecified...
<beach>
ldbeth: Then, for the characters, it is faster to have a vector of length 245 (256?), but that assumes the character domain is compact, which you haven't told us about. If it is not, but it doesn't change very often, a binary search is faster than a hash table, so a vector with the sorted character keys in it.
<beach>
And if the character domain doesn't change very often at all, the fastest way is to compile a function that executes a decision tree.
<beach>
ldbeth: There are just too many options to be able to say anything general without knowing all these characteristics.
judson_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Aurora_v_kosmose has joined #lisp
<beach>
And you haven't told us what the objective is. Speed? Space?
<ldbeth>
beach: my intention is to represent an acyclic finite state automata for spell checking against a large dictionary
<ldbeth>
and that dictionary should be able to save to disk
<beach>
So what is the n?
<ldbeth>
it is the total states in automata, and it dependes on the size of dictionary
shka_ has joined #lisp
<beach>
So the value of the mapping n X c is another state?
<ldbeth>
n * c -> n is a function given the current state and a char, find the next state
<beach>
For spell checking, I would go for a binary search rather than a hash table.
<Nilby>
anything like a dictionary seem like character tries would be good
<beach>
I guess that does make it a trie.
<ldbeth>
the acyclic fsm is a minimized trie
<beach>
Anyway, don't do a hash table for the characters. For spell checking, I would do a full-size vector on the top level and a binary search on the following levels.
troydm has quit [Quit: What is Hope? That all of your wishes and all of your dreams come true? To turn back time because things were not supposed to happen like that (C) Rau Le Creuset]
<ldbeth>
beach: i think you've made a nice suggestion
<beach>
Great!
<ldbeth>
since the words in dictionary are at least 3 chars long, I can make 2 levels of full-size vector and then do tree search
troydm has joined #lisp
orivej has quit [Ping timeout: 240 seconds]
<beach>
That would waste a lot of space I am afraid. I am guessing that already at the second level, the domain is no longer very compact.
moon-child has joined #lisp
aartaka has joined #lisp
frost-lab has joined #lisp
wxie has joined #lisp
nkatte has joined #lisp
andreyorst has joined #lisp
mrchampion_ has quit [Remote host closed the connection]
toorevitimirp has joined #lisp
ldbeth has quit [Quit: ERC (IRC client for Emacs 27.1)]
<lotuseater>
beach: about 27 calls of CHANGE-CLASS in the current (master) Cleavir source code :)
andreyorst` has joined #lisp
andreyorst` has quit [Remote host closed the connection]
andreyorst` has joined #lisp
<no-defun-allowed>
Without CHANGE-CLASS, you can't write OVERWRITE-INSTANCE, which is a very fun thing to have around.
<lotuseater>
oh tell me more, never used it yet
<flip214>
no-defun-allowed: you could use MOP to individually clear every instance slot
<lotuseater>
it does not seem to be part of the standard specification
andreyorst has quit [Ping timeout: 260 seconds]
<no-defun-allowed>
OVERWRITE-INSTANCE is a function I wrote somewhere in Netfarm, so that I could...overwrite an instance. It is not too complicated.
<no-defun-allowed>
I hope I don't use it ever; it probably handles unbound slots wrong, and also probably shouldn't call INITIALIZE-INSTANCE again. But it was quite fun.
liberliver has joined #lisp
<lotuseater>
okay not too complicated sounds good for me
<no-defun-allowed>
I would have used it to store a "reference" object with the hash of an object I actually wanted to put in place, so that I can overwrite them lazily.
<lotuseater>
using the closer-mop lib is more portable, isn't it?
<no-defun-allowed>
Yes, using closer-mop is preferable over the MOP package of your implementation.
andreyorst` has quit [Quit: andreyorst`]
andreyorst` has joined #lisp
KREYREEN has quit [Remote host closed the connection]
malm has joined #lisp
KREYREEN has joined #lisp
Fare has quit [Ping timeout: 264 seconds]
random-nick has joined #lisp
Cymew has joined #lisp
hiroaki has quit [Remote host closed the connection]
<no-defun-allowed>
"The best of intentions: EQUAL Rights - and Wrongs - in Lisp"
<nij>
Will read!
<beach>
That one.
<nij>
Thanks for pointing it out :))
<beach>
nij: So there is no such thing as "value equality" independent of the situation.
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #lisp
<beach>
nij: The mathematical equality you are referring to works only in the very restricted universe of mathematicians, where most things are numbers, or isomorphic to numbers.
<beach>
nij: So welcome to the world of software development.
nkatte has quit [Ping timeout: 272 seconds]
<nij>
Highlight: There is no uniquely determined equality function for complex structures--there are only arbitrary ones.
<beach>
That's basically what I said.
<beach>
In most cases, you need to supply your own.
<nij>
So, if I want strict mathematical sense of equal, should I just use equalp?
<nij>
Or there is something called 'equalpp?
<beach>
If you want strict mathematical sense, you need to use numbers as your only data type.
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #lisp
hugh_marera has quit [Quit: Connection closed]
<no-defun-allowed>
It is impossible to decide if two terms in the lambda calculus are equivalent, so I am sure mathematicians get into hairy situations too. "where most things are numbers, or isomorphic to numbers" doesn't hold for those situations, of course.
<beach>
nij: Imagine you have several graphs of objects. Now you want to check whether two objects are "equal in the strict mathematical sense". Are you suggesting that this equality predicate will then have to solve the graph isomorphism problem?
<beach>
no-defun-allowed: Sure, though mathematicians are not that much into decidability. That's mainly for CS people.
<no-defun-allowed>
Ouch, I was going to mention graphs, but NP isn't quite undecidable. /me needs graph isomorphism for her idea of approximating protocol equivalence.
<nij>
Oh now I get it.
hugh_marera has joined #lisp
<no-defun-allowed>
beach: Oh, okay.
<nij>
Oh no. It's indeed hairy :(
<nij>
How then would one really decide which to use? By reading the source code of all of them?
<beach>
By reading the Common Lisp HyperSpec definition.
<nij>
It could cause highly unexpected error!!
<nij>
Oh.. is CLHS definition the official one?
<beach>
Er, yes.
<beach>
That's the HTML version of the standard.
<no-defun-allowed>
As close to an official definition as you can get without spending money.
<nij>
New here :) Thanks!
<beach>
nij: Again, you will usually have to define your own equality predicate. If what you need happens to correspond to the definition of one of the existing ones, then use it.
<no-defun-allowed>
Yes, the Common Lisp HyperSpec defines the semantics of such predicates, as well as everything else in Common Lisp (except the parts it leaves undefined for whatever reason).
<beach>
And equality predicates are not one of those parts as I recall.
<no-defun-allowed>
Indeed, but I was expecting someone to say "no, the standard leaves some behaviour undefined", so I put the part in parens in.
<beach>
Good planning! :)
<phoe>
good morning
<beach>
Hey phoe.
<no-defun-allowed>
Hello phoe.
<phoe>
hi hey
<beach>
phoe: I am still your friend. Though not a very close one, I'll admit. :)
<phoe>
oh my god that's dangerous
<beach>
?
<beach>
Oh, being your friend?
<adlai>
nij: keep an eye out for :test and :test-not keyword arguments that are taken by many of the sequence functions, and allow you to supply your own customized equality predicates
<phoe>
yes
<beach>
phoe: We might want to keep it to ourselves.
<phoe>
beach: OK
<phoe>
let's do it that way
<beach>
Yeah. :)
<phoe>
:D
<no-defun-allowed>
Oh, speaking of protocols, how would you define a protocol in a rigorous, but hopefully not too tedious, manner? I am currently thinking operations (with optional argument and return types), some test cases, and some representation of how I should expect the state of objects to change, should there be state.
<phoe>
no-defun-allowed: no protocol classes?
<adlai>
your question seems hopelessly abstract
<beach>
no-defun-allowed: Can I assume you read the section of my book about protocols?
<no-defun-allowed>
phoe: Well, a type is a bundle of operations that can be applied to an object of that type, in my head.
amb007 has quit [Read error: Connection reset by peer]
<no-defun-allowed>
beach: Yes, from memory you define a protocol as a set of types and functions?
amb007 has joined #lisp
<beach>
Yes.
<beach>
no-defun-allowed: I think what you suggest is basically it.
<beach>
Plus exceptional situations and such.
<no-defun-allowed>
Gotcha.
<beach>
The more you can refer to other protocol operations, the better. Like, A can be applied to an object O only if B returns true for O.
<beach>
Or, if A returns ??? for an object then B can be applied to that object...
<no-defun-allowed>
Additionally speaking of Netfarm (with OVERWRITE-INSTANCE), I want to have a go at using definitions of protocols to create glue logic between protocols that are not compatible, but could be made compatible with such logic.
<beach>
Example, you can POP the stack only if EMPTY returns FALSE.
pve has joined #lisp
<beach>
That's an interesting problem.
<beach>
Sounds complicated.
<no-defun-allowed>
beach: In a short article I wrote, I imagined a finite state machine, where each state had a predicate that would return true if the object was in that state, and some functions to transition between them. But that does not help for your operation A, which may not cause a transition, and it is also no good for modelling a stack.
<beach>
Yes, things might be more complicated than that. Transitions might depend on the history of operations applied.
<no-defun-allowed>
Well, I don't like the other approaches to developing protocols in a decentralised way, because they are too concerned with representations and not operations.
galex-713 has joined #lisp
<lotuseater>
oh damn, coming back short to the equal question, seems like SXHASH just hashes on the array dimension. interesting
<beach>
By "decentralised", you mean by any old developer without coordination?
<beach>
no-defun-allowed: ^
<no-defun-allowed>
If you concern yourself with operations and not representation, you already get some leeway, but translating operations somehow seems less hopeless than representation.
<no-defun-allowed>
Yes.
<beach>
I totally agree.
<beach>
Many developers are not very good ones.
<no-defun-allowed>
Suppose I have a server which implements protocol A, and you make a server which implements an extension of A, call it A'. Now what should I do if I receive an object from your protocol? I can either just drop your extensions, or see how much of your extension I can present to the client. (I want to do the latter, but in my opinion that's the less interesting question of this one and the next one.)
zabow has joined #lisp
nij has quit [Ping timeout: 260 seconds]
<no-defun-allowed>
Now what if, somewhere on Equivalent Earth, an equivalent no-defun-allowed creates an implementation of protocol B, and I somehow find their objects laying around somewhere. For some definition of "isomorphic", if those protocols are isomorphic, then I could use those objects like they were from protocol A.
<no-defun-allowed>
"...laying around somewhere?"
<White_Flame>
"LYING around somewhere" </my mom>
zabow has left #lisp [#lisp]
srandon111 has joined #lisp
<no-defun-allowed>
adlai: Perhaps, but I think a sufficiently good answer would save everyone from forwards, backwards and cross -compatibility woes.
<srandon111>
guys does sbcl statically compiles by default? if not, how can i build a standalone statically compiled executable ?
<no-defun-allowed>
Compiling is a different operation to generating an executable.
<beach>
srandon111: "statically"?
<srandon111>
beach, yes
<no-defun-allowed>
As opposed to "dynamic compilation" (also "just-in-time compiling"), SBCL would be mostly "static", I suppose.
<beach>
srandon111: What does it mean?
mbomba has joined #lisp
<beach>
srandon111: The semantics of a Common Lisp program can be defined by a suite of interactions, starting with the initial image.
<srandon111>
beach, do you know about the dynamic libraries (in gnu/linux are the .so, whilee on Windows are the .dll), well instead of relying on these ones, you basically put everything in the executable image...
<beach>
srandon111: This is different from most "batch" programming languages.
<srandon111>
so that you do not have external deps
<srandon111>
no-defun-allowed, why mostly static?
<no-defun-allowed>
I don't know of a way to create static executables with SBCL; SAVE-LISP-AND-DIE usually creates dynamically linked executables.
<srandon111>
no-defun-allowed, ok you said a different thing before
<beach>
srandon111: If you just use save-lisp-and-die in SBCL, you can generate an executable from the current state of your system.
<srandon111>
no-defun-allowed, you are confusing me
<srandon111>
no-defun-allowed, i know
<srandon111>
beach, that's interesting thanks for giving me this info
<no-defun-allowed>
I don't think anyone calls static linking "static compilation".
<beach>
Sure.
<no-defun-allowed>
Er, you use lld to see the libraries an executable depends on under Linux, right?
hiroaki has quit [Ping timeout: 240 seconds]
<no-defun-allowed>
ldd, not lld
<no-defun-allowed>
Phew, lld told me to use ld.lld, which did not want anything to do with my SBCL image.
sirvolta has quit [Ping timeout: 272 seconds]
<no-defun-allowed>
srandon111: SBCL does create dynamically-linked executables, and there aren't any relevant arguments to save-lisp-and die that would cause it to create statically-linked executables. You might want to ask in #sbcl, but using the phrase "statically-linked executable" instead of "static compilation".
* beach
could not, as usual, have guessed what was meant from the terminology that was used.
<no-defun-allowed>
I am hoping "static linking" and "dynamic linking" are more familiar? I don't usually discuss Unix executables.
<lotuseater>
and it's important not to use it in Emacs/SLIME since single threading
<beach>
Speaking of which, I just noticed I have a signed copy of "Linkers and Loaders" by John Levine.
<beach>
I don't think I ever met him, so he must have mailed it to me.
iskander has quit [Ping timeout: 264 seconds]
iskander has joined #lisp
<beach>
I especially enjoyed the chapter on the consequences of dynamic linking in Unix to the complexity of the entire system, which GOTs and whatnot.
urek has joined #lisp
<srandon111>
no-defun-allowed, ok so you know no wy to create a statically-linked executable with sbcl ?
<no-defun-allowed>
That is correct.
<lotuseater>
the CFFI manual contains a little section about static linking with ASDF
<oni-on-ion>
cool, that looks like the answer to a question i asked yesterday.
<lotuseater>
okay well then :)
zaquest has joined #lisp
zaquest has quit [Remote host closed the connection]
GZJ0X_ has quit [Remote host closed the connection]
<lotuseater>
for commercial use cases implementations like LispWorks may have better built-in support for it
GZJ0X_ has joined #lisp
hendursaga has quit [Ping timeout: 240 seconds]
GZJ0X_ has quit [Remote host closed the connection]
<srandon111>
oni-on-ion which question ?
GZJ0X_ has joined #lisp
huskyhaskell has joined #lisp
luna_is_here has quit [Ping timeout: 272 seconds]
huskyhaskell has left #lisp ["ERC (IRC client for Emacs 28.0.50)"]
hnOsmium0001 has quit [Quit: Connection closed for inactivity]
heisig has joined #lisp
hydan has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
luna_is_here has joined #lisp
luni has joined #lisp
luna_is_here has quit [Quit: luna_is_here]
luna_is_here has joined #lisp
nij has joined #lisp
<nij>
Hello, I tried to loop over an array and collect some computed stuff into a 'tmplist using 'nconc.. but after evaluating the loop, 'tmplist remains its initial value. Why so? https://bpa.st/JYGQ
<nij>
(There are many many bad styles.. any suggestions on styles would be appreciated to!)
<nij>
s/to/too
<no-defun-allowed>
You should use the return value of NCONC, and not use it "for effect". And you should not use destructive functions on quoted datum.
<beach>
nij: SETQ on an undefined variable is undefined behavior.
<beach>
nij: And put the DO LOOP keyword first on a line.
<beach>
And indent using SLIME.
<nij>
beach: I'm using SLIME and indent by pressing M-q.
<beach>
Then put the DO keyword first on a line and indent again.
<beach>
nij: And what is the 'nil at the end?
<beach>
nij: 'nil means you return a symbol.
<nij>
If cond fails, "do nothing"?
<no-defun-allowed>
Er, does M-q indent? I thought it wraps your text to 72 columns, which is ridiculous for code.
<beach>
But in fact, your entire IF expression is evaluated for side effect only as far as I can tell.
<nij>
no-defun-allowed: This is exactly where I learned to use nconc.
<nij>
In particular, it reads (nconc x y) => (A B C D E F)
<nij>
x => (A B C D E F)
<no-defun-allowed>
The description does not help my case, but it is usually considered bad style.
<nij>
The value of x /was/ (A B C). But after being nconc-ed, x changes.
<beach>
no-defun-allowed: Isn't NCONC one of the functions with a mandatory side destructive side effect.
<no-defun-allowed>
Note that the other examples of NCONC also SETQ the return value.
<no-defun-allowed>
beach: It is indeed.
<no-defun-allowed>
Maybe I was thinking of SORT.
<nij>
@@
<nij>
So....... why isn't my tmplist changed?
luni has left #lisp [#lisp]
<nij>
I loaded (nconc tmplist (list 1 2)) by hand.. and it did change the value of tmplist.
<no-defun-allowed>
I am wondering how you got anything to happen still, as (length (- spdata 2)) could not possibly return a value if SPDATA is an array.
urek__ has joined #lisp
<nij>
OH dang =_=
<nij>
Maybe that's the reason! I missed it.
<no-defun-allowed>
Was a relevant error not signalled?
urek has quit [Ping timeout: 258 seconds]
<nij>
It did behave unexpectedly, but I didn't notice any error.
<mfiano>
Then you are not even evaluating it or you are altering the default safety level.
<nij>
Fixed....... now it works =_+ the problem isn't in nconc.
<no-defun-allowed>
Frobbing how?
<nij>
Ok.. so I think I understand nconc correctly.
<beach>
nij: You are still not allowed to modify literal data.
<nij>
Now I should try to fix the style. As you suggested, no-defun-allowed, I should use "loop.. under" and "collect"?
<nij>
beach: Where did I modify literal data?
<beach>
'(0 0) is literal data and you are modifying it.
<nij>
Why shouldn't I modify '(0 0)
<mfiano>
Yes this is undefined behavior, and bad style all over the place. But undefined behavior could do anything at all.
<no-defun-allowed>
(loop for x below 10 collecting x) ⇒ (0 1 2 3 4 5 6 7 8 9)
<beach>
nij: Because '(0 0) is literal data and you are not allowed to modify literal data.
<nij>
beach: But it did work on my system..
<mfiano>
'(0 0) is a list literal and the compiler can choose to do anything if you modify it.
<mfiano>
Did work, and will always work is a big difference. Undefined is undefined
<beach>
nij: "Undefined behavior" means that it may work on some implementations and not on others.
<no-defun-allowed>
nij: And on someone else's system, it is allowed to send them nasal demons instead.
<mfiano>
Or it may work on one implementation, and may not work at another time on the same implementation.
<nij>
So I shouldn't even do something like this? :
<beach>
nij: In this case, if you are using SBCL and you stick your code in a function it won't work the second time you run it.
<nij>
(nconc '(0 0) '(1 2))
<no-defun-allowed>
For the avoidance of doubt, that is not a very nice thing to send someone.
<nij>
I see. I will take it seriously. How should I fix my code?
wxie has quit [Ping timeout: 265 seconds]
<nij>
.. well I might just look into 'collect and use it.
<beach>
nij: Try (defun ff (x) (nconc '(0) x)) then (ff '(10)) and (ff '(20))
<mfiano>
Start by forgetting SETQ even exists, and use SETF. Secondly, make proper use of lexical variables. You do not need global state here.
<no-defun-allowed>
You could use (list 0 0) to create a fresh list, or (ideally, in my opinion) use COLLECT in LOOP to create the list. But the latter won't produce the (0 0) prefix.
<beach>
nij: It is important that you understand why that does what it does.
<nij>
no-defun-allowed: You are suggesting I use (list 0 0) instead of '(0 0)?
<no-defun-allowed>
Yes.
<nij>
beach: Oh that did fail. Thanks for the example!
<no-defun-allowed>
Oh, if you don't use COLLECT but you create a list (without cleverly holding a reference to the end of the list somewhere), appending to the end will result in O(n^2) time complexity.
<nij>
no-defun-allowed: I see.
<nij>
mfiano: I used SETQ too much in elisp :(
<nij>
To use SETF I should understand what a place is.
<nij>
But I never succeeded. Will try again.
<mfiano>
Use setf in elisp too so you don't forget that SETQ is a historical artifact
<no-defun-allowed>
(setq x v) does the same thing as (setf x v)
<nij>
mfiano: that's surprising to know cuz SETQ appears so often in elisp
<nij>
So.. lessons learned: 1. Use (list 1 1) instead of '(1 1) if it is to be modified. 2. Use 'collect and "loop .. below". 3. Use 'setf instead of 'setq.
<nij>
Thank you all so much!
<mfiano>
Do not try to draw parallels to other dialects as a beginner. It will not end well.
<Alfr_>
nij, usually (nconc list lists) will modify list and you can skip the setf, but if list is nil, then list will still be nil and nconc's result may differ.
<nij>
I see.
<nij>
Yeah I am tring to forget elisp..
nij` has joined #lisp
nij has quit [Remote host closed the connection]
treflip has joined #lisp
rumbler31 has quit [Read error: Connection reset by peer]
<dim>
mfiano: I think we can say this: setf is a macro that uses setq when needed, so any time you write setq, you can write setf and have the exact same effects ; then in some cases you can use setf where setq would not be supported
rumbler31 has joined #lisp
<dim>
mmm, I guess that was for nij actually?
<dim>
not following closely enough sorry folks
<nij`>
Oh I got logged out :()
<nij`>
Hopefully I didn't miss too much.
<nij`>
<nij`>
I will have to understand 'setf.
Stanley00 has quit []
<phoe>
nij`: no problem, this channel is logged
<phoe>
so you can see what you missed.
<easye>
"This will go down on your *permanent record*."
<shinohai>
"But muh GDPR!"
spal is now known as susam_
susam_ is now known as spal
srandon111 has quit [Ping timeout: 240 seconds]
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #lisp
rumbler31 has quit [Read error: Connection reset by peer]
rumbler31 has joined #lisp
srandon111 has joined #lisp
Posterdati has quit [Ping timeout: 256 seconds]
galex-713 has quit [Ping timeout: 272 seconds]
surabax has joined #lisp
galex-713 has joined #lisp
<phoe>
yes, GDPR stands for Global Data Permanent Record
galex-713 has quit [Ping timeout: 264 seconds]
galex-713 has joined #lisp
Posterdati has joined #lisp
ljavorsk has joined #lisp
mbomba has quit [Quit: WeeChat 3.0]
<harlchen>
whats the easiest way to only get local package warnings/errors on test-op's in (asdf:defsystem '.../tests ... ) instead of redefining of external defgenerics e.g. 'WARNING: redefining LOG4CL-IMPL::PROPERTY-ALIST in DEFGENERIC' and 'cl-fad.asd" contains definition for system "cl-fad-test". Please only define "cl-fad" and secondary systems ....' ?
<Xach>
harlchen: if you find a way, please let me know. i would like something very similar.
<flip214>
srandon111: because it's an engineering language, with lots of libraries
<phoe>
srandon111: Common Lisp Recipes
<srandon111>
flip214, what do you mean by engineering lanaguge?
<srandon111>
flip214, yes land of lisp is cool
urek__ has joined #lisp
<flip214>
well, scheme is a small, clean language, used to proof CS lemmas
<flip214>
CL is a heavy thing you can solve real-world issues with
<aeth>
Land of Lisp has the unfortunate distinction of being a Lisp book that didn't age well, even a few years after release. e.g. relying on CLISP right around when CLISP died, or mentioning Arc as an up-and-coming Lisp, etc.
<aeth>
really unfortunate timing for a bunch of things
<flip214>
aeth: well, write 1024 books with 10 forecasts, then you'll have 1 real hit
GZJ0X_ has quit [Remote host closed the connection]
urek has quit [Ping timeout: 264 seconds]
GZJ0X_ has joined #lisp
<wsinatra>
Let over Lambda is a good read if you're curious about macros
<wsinatra>
I'll second CLR as well, good suggestion phoe
GZJ0X_ has quit [Read error: Connection reset by peer]
<flip214>
minion: tell srandon111 about Loλ
<minion>
Loλ: An error was encountered in lookup: #\GREEK_SMALL_LETTER_LAMDA (code 955) is not a LATIN-1 character..
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #lisp
GZJ0X_ has quit [Remote host closed the connection]
judson_ has joined #lisp
cosimone has joined #lisp
malm has quit [Ping timeout: 264 seconds]
<pfdietz>
How is CLISP dead? Not disputing that, but I want to know how that's defined.
Fare has joined #lisp
malm has joined #lisp
<jackdaniel>
from my experience on this channel: everything what is not hosted on github and doesn't have at least 3 commits / month is essentially dead, stinks and shouldn't be used by anyone
niceplaces has quit [Ping timeout: 256 seconds]
<jackdaniel>
(I don't share that opinion)
surabax_ has joined #lisp
niceplace has joined #lisp
<ioa>
I thought common lisp projects are mainly hosted on gitlab.common-lisp.net not github :)
<jackdaniel>
what undeniably proves, that lisp is dead ;-)
<ioa>
XD
<srandon111>
minion, how racist is minion by only allowing latin chars and not greek chars???
<minion>
i agree - how racist is minion by only allowing latin chars and not greek chars
<ioa>
(I disagree with that opinion as well btw ^^ )
<minion>
соме руссиан цхарацтерс фор ыоу: An error was encountered in lookup: #\CYRILLIC_SMALL_LETTER_ES (code 1089) is not a LATIN-1 character..
<srandon111>
damn
<srandon111>
it's also racist against russians...
<srandon111>
i wonder if minion is chinese
surabax has quit [Ping timeout: 265 seconds]
srandon111 is now known as sookablyat
* ioa
waiting to see sookablyat's chinese phrase ^^
orivej has joined #lisp
aeth_ has joined #lisp
shifty has quit [Ping timeout: 256 seconds]
<sookablyat>
奴才给你一些中文。! minion
<sookablyat>
take this
<sookablyat>
damn minion does not complain about chinese... so he definitely is half latin half chinese...
<sookablyat>
probably a chinese father and a latin mother... coming from romania... yes... this explains his hate for russian
<aeth_>
pfdietz: Technically, CLISP is more undead than dead. Last release 2010-07-07 (more than 10 years ago at this point). It still gets commits, but it's not active enough to push a new release so most people have moved on to other CLs. https://clisp.sourceforge.io/
aeth has quit [Disconnected by services]
aeth_ is now known as aeth
notzmv` has joined #lisp
<sookablyat>
aeth, wait we were tralking about common lisp not clisp
<aeth>
jackdaniel: When SBCL is getting releases once-a-month and CLISP is getting releases once-a-decade, I can't help but compare the activity levels between the two.
<phoe>
clisp is not active enough to merge PLNs though
<phoe>
that's a pain because more and more code assumes that PLNs are present
<sookablyat>
minion, tell phoe to slow down
<minion>
phoe: does torturing a poor bot with things beyond its comprehension please you?
<aeth>
Right, CLISP was already behind major implementations on popular optional-but-not-mandated-by-the-standard features (e.g. it doesn't have double-float or single-float specialized arrays)
<aeth>
And it's only going further behind by not having stuff like PLN
<aeth>
More and more code will either not work well or not work on CLISP over time.
<phoe>
sookablyat: wait, how does that work
surabax_ is now known as surabax
<sookablyat>
phoe, what?
<phoe>
you told minion to tell me something and minion actually told me something
<phoe>
interesting
<sookablyat>
phoe, well you just use minion tell <user> <something>
<phoe>
minion: tell sookablyat something
<minion>
Sorry, I couldn't find anything in the database for ``thing''.
<jackdaniel>
I'm impressed with sbcl devs performance too; I'm still not sure how it maps on dying. I'm not dead because I don't run as fast as [put some athlet here]. I'm dead because they torture minion.
<phoe>
weird
<sookablyat>
minion, tell phoe how to use you
<minion>
phoe: does torturing a poor bot with things beyond its comprehension please you?
* phoe
hides
<jackdaniel>
sookablyat: please stop generating noise on the channel
<sookablyat>
jackdaniel, i was helping a comrade
<jackdaniel>
(you may query minion)
<aeth>
jackdaniel: If something is a tiny Common Lisp library written in portable CL with no CFFI dependencies, then it's very likely that it'll still run 15-25 years later, perhaps without modification.
<jackdaniel>
still not the part I disagree with
<aeth>
jackdaniel: If something is a Common Lisp implementation and it doesn't push out a release in the past 5 years, it's essentially dead. There are too many things that change over that time period. phoe brought up an excellent example in package-local-nicknames. Lots of libraries depend on those now, and thus can no longer run on CLISP.
<Nilby>
I think ECL has replaced CLisp's main ecological niche, being compiled from relatively portable C.
<aeth>
In a sense, you can have a tiny Common Lisp library run without modifications decades later because all of the burden to avoid bitrot is shifted to the implementations, which must receive updates.
<jackdaniel>
what can I tell, your description only fits what I've said at the beginning (of course not literally)
<mfiano>
I guess CL is dead since it hasn't release a new standard
<jackdaniel>
Nilby: clisp does not compile to portable C
<ioa>
what are PLNs?
<phoe>
but it compiles *from* portable C
<jackdaniel>
it is written in portable C (and ECL is not exactly portable - it could be with some push)
<phoe>
ioa: package-local nicknames
<ioa>
thanks
<phoe>
allowing you to e.g. use a:foo instead of alexandria:foo inside your package, and your package only
nij```` has joined #lisp
<phoe>
these work similarly global nicknames, except they don't pollute the global namespace and therefore do not generate conflicts.
<ioa>
I know what are package local nicknames
<phoe>
oh! sorry
<ioa>
thanks :)
<aeth>
jackdaniel: Let's review. <aeth> ... CLISP died ... <pfdietz> How is CLISP dead? ... <jackdaniel> [strawman of what a "dead" project is, not what I meant to say]
<ioa>
I am just bad with shortcuts
<ioa>
s/shortcuts/abbreviations/
<Nilby>
jackdaniel: the _from_ C is the important thing I think. Compiler output is less likely to be portable.
phoe6_ has joined #lisp
<jackdaniel>
my snarky remark sense was: people dub things dead based on activity and I find that silly
<ioa>
np :P
<aeth>
jackdaniel: I'm not sure how I can even in good faith address your strawman. But let me. "from my experience on this channel" so you're just lumping my opinion in with a vague channel sentiment. "everything what is not hosted on github" I only use Gitlab. "and doesn't have at least 3 commits / month is essentially dead" how about 1 release in the past 5-10 years? Even 10 would make CLISP dead.
<aeth>
"stinks and shouldn't be used by anyone" I never said no one should use CLISP.
treflip has quit [Quit: WeeChat 2.6]
<aeth>
"(I don't share that opinion)" I don't, either. You set up a strawman to debunk it. "what undeniably proves, that lisp is dead" and we're talking about CLISP, not CL
<pfdietz>
The niche of compiled from C is important for getting SBCL into Debian, right?
<jackdaniel>
as pointed out above, my remark was snarky - I've spelled out what it meant - I'm getting back to code because I'm not enjoying this discussion
nij``` has quit [Ping timeout: 260 seconds]
<aeth>
Let me clarify what I meant: Project "death" from lack of releases has nothing to do with lack of activity. It's death from a thousand papercuts. While Common Lisp is a solid foundation and your *.lisp files won't break, Common Lisp implementations will bitrot over time as they lack non-standard features people start assuming (like PLN) and lack platform support that people start wanting (I'm guessing Apple M1 counts there).
<aeth>
The attitude that a project can have no updates in decades and still run only applies to Common Lisp code itself, not code that relies on FFI and not Common Lisp implementation code, and it's precisely because Common Lisp code shifts the burden to remain relevant and alive to the Common Lisp implementations.
<Nilby>
CLisp won't really die for a long time, since it can be basiclly built from a C compiler, it will live on in various distributions. The self-hosted lisps feel like they really need active development to keep a binary running on current versions of a bunch of platforms.
<pfdietz>
And even in Common Lisp code, rot can occur if you have dependencies to other systems.
<aeth>
pfdietz: Right, even if your dependency switches to package local nicknames and not your project, that will break it on CLISP
<scymtym>
or if the code is non-conforming in ways that implementations didn't catch before but now do
<pfdietz>
Type declarations in slots in sbcl, for example.
<pfdietz>
Another popular problem source is use of internal sbcl packages.
Josh_2 has joined #lisp
<wsinatra>
aeth: at least with SBCL they're actively trying to get apple M1 hardware to port SBCL to the platform
<aeth>
pfdietz: There's still no portable equivalent to sb-unicode that does everything sb-unicode does. You could combine together maybe 2-3 libraries that are slower and have a worse API.
<scymtym>
(i'm not trying to point out flaws in aeth's argument, by the way. they said "portable CL")
<wsinatra>
people are very much trying to maintain and expand the implementations
cosimone has quit [Remote host closed the connection]
cosimone has joined #lisp
<_death>
my prediction is that 2021 will see a clisp release
<pfdietz>
That would be nice.
<Nilby>
Maybe keeping CLisp frozen in time is a good test for portable CL code.
<aeth>
_death: were we poking you a hundred times or does only "_death" poke you?
judson_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<_death>
only _death.. though the indicator is merely a color change
judson_ has joined #lisp
<aeth>
pfdietz: I guess another way to think about things is that a portable Common Lisp project, even if it doesn't get active updates in 10-20 years, will still run... on *current* Lisp implementations. This is because the dependencies of the project can shift, thus making the project only run on current implementations. But it will still run. Unless, as scymtym said, it wasn't truly portable in the first place.
<aeth>
(Of course, FFI can still break this assumption since those foreign dependencies can break.)
<pfdietz>
I think this also puts constraints on other CL systems one depends on, that they not gratuitously change their APIs. For example, don't export new symbols from your packages. This implies that if you want to extend the API of such a system you need to create new packages containing the updates. Versioned packages?
toorevitimirp has quit [Remote host closed the connection]
<aeth>
pfdietz: Well, generally, the advice to handle that is to not USE, which is why package local nicknames happened in the first place
toorevitimirp has joined #lisp
<aeth>
Then the only issue is deleting changes, which is why some library ecosystems rely on things like semver (which, technically in CL, would have to be incremented with every new EXPORT as you said).
gko_ has joined #lisp
<aeth>
ASDF (technically, UIOP) has the mechanisms for this by parsing version strings, but Quicklisp afaik does not.
<aeth>
Afaik, you would need versioned packages to make it work with Quicklisp because Quicklisp wants everything in a dist to be able to be loaded in one image. Either that, or local environments that can have incompatible packages. That would still be messy if you e.g. wanted to depend on two libraries that depended on two versions of uiop
dyelar has joined #lisp
diamondbond has quit [Ping timeout: 258 seconds]
X-Scale has joined #lisp
_heisig has joined #lisp
<aeth>
pfdietz: Thanks for raising the issue of "If semver is used in Common Lisp, should every new export in a package require a new major version in case someone USEs the package even though they shouldn't do that?" that I don't think anyone has thought about before.
<aeth>
I think versioned packages would be a given if you do this, though. Then the semver major version would be tied to the package, so e.g. foobar.3 would correspond to the interface of 3.x.y
diamondbond has joined #lisp
heisig has quit [Ping timeout: 258 seconds]
EvW has quit [Ping timeout: 258 seconds]
jurov has joined #lisp
scymtym has quit [Ping timeout: 264 seconds]
zcheng3 has joined #lisp
nij````` has joined #lisp
nij```` has quit [Ping timeout: 260 seconds]
mrchampion has joined #lisp
jw4 has quit [Quit: tot siens]
jw4 has joined #lisp
Fare has quit [Ping timeout: 264 seconds]
gxt__ has quit [Remote host closed the connection]
gxt__ has joined #lisp
* nij`````
wonders how to master LOOP.
<phoe>
nij`````: that's a lot of backticks
<phoe>
but anyway - just use it, and read the PCL chapter on loop
<nij`````>
I am using erc and it has logged me out too many times.. sorry. I should regain nij.
<nij`````>
Should one understand its source code at some point?
<phoe>
no
<nij`````>
Or it is really another language embedded in CL.. so don't bother.
<phoe>
LOOP is one really damn complicated thing
tfb has quit [Remote host closed the connection]
<phoe>
you can read the SICL LOOP sources but the SBCL LOOP is complicated
tfb has joined #lisp
<phoe>
and complex
<nij`````>
OK. Got it!
wsinatra_ has joined #lisp
<nij`````>
Yeah I tried and failed.
<phoe>
that's because LOOP is a domain specific language embedded in Common Lisp.
<nij`````>
Ah.. I see.
tfb has quit [Remote host closed the connection]
<phoe>
a language for iterating
<phoe>
and you were essentially peeking at the compiler for that language.
tfb has joined #lisp
wsinatra has quit [Read error: Connection reset by peer]
<nij`````>
I came to lisp with the curiosity of how lisp can beautifully builds it up.
<phoe>
well because it does build it up
<nij`````>
Most other macros seem to be doable. LOOP on the other hand seems to be an anamoly.
<phoe>
but it doesn't mean that the complexity just goes away
tfb has quit [Remote host closed the connection]
skapata has quit [Remote host closed the connection]
tfb has joined #lisp
<phoe>
yes, that's because LOOP has tons of loop keywords inside it and it has to support various combinations and uses and use styles of them
<phoe>
it's really kind of a language of its own.
<aeth>
nij`````: DO is simple if you want to learn iteration
<nij`````>
Right..
tfb has quit [Remote host closed the connection]
<nij`````>
aeth: You mean its source code?
<phoe>
yes, DO and DOLIST and DOTIMES have pretty simple expansions
tfb has joined #lisp
<phoe>
their source code too, I presume
<nij`````>
What are other amazing macros? I hope eventually I can learn all the major examples.
<aeth>
nij`````: In most implementations a DOLIST and a DOTIMES can expand into a DO which can expand into a TAGBODY with GO (i.e. contained gotos) with some SETFs and LETs and stuff
<nij`````>
phoe: Isn't do a keyword inside LOOP?
tfb has quit [Remote host closed the connection]
<aeth>
LOOP on the other hand leaves room for arbitrarily complex implementations since you can always optimize your LOOP more.
tfb has joined #lisp
scymtym has joined #lisp
<aeth>
In fact, I doubt any LOOP is as complicated as it could be, e.g. loop unrolling
<phoe>
nij`````: it is, but we mean the macro CL:DO
<nij`````>
phoe aeth : GOT IT!
johnjay has quit [Ping timeout: 240 seconds]
tfb has quit [Remote host closed the connection]
<phoe>
still, these are macros, so reading and writing them might be complicated. try to macroexpand/macrostep them as well to get a feeling of what they expand into.
<aeth>
a LOOP that is known to iterate, say, 4 times could unroll in someone's implementation. Technically, DO could, too, but DO is far more likely just to forever stay that simple contained goto
tfb has joined #lisp
<nij`````>
But can I say that CL-LOOP is amazing because it first got translated into lisp, and then to machine codes?
<phoe>
not really "translated"
<nij`````>
while in other languages LOOPs are directly translated into lower level codes.
tfb has quit [Remote host closed the connection]
tfb has joined #lisp
<phoe>
LOOP is just a big function that grabs a block of Lisp data and produces complex Lisp code that performs iteration
<nij`````>
Beautiful.
<phoe>
and that function is called at compilation-time, or more precisely, at macroexpansion-time
<nij`````>
I'm stunned.
tfb has quit [Remote host closed the connection]
<aeth>
Common Lisp basically has a programmable compiler
<phoe>
and the result of that function is spliced into the surrounding raw lisp code, and then compiled.
<aeth>
Not just macros, you even have EVAL-WHEN
sjl has joined #lisp
<nij`````>
aeth: Could you elaborate?
<aeth>
There are a bunch of known stages that can run arbitrary code (and who knows how many unknown stages)
<aeth>
the reader macro #. is used to evaluate at read time, e.g. #.(+ 1 1)
<aeth>
there are probably a few more known stages
<nij`````>
What do you mean by known stages?
<aeth>
The standard specifies some compiler stages because you can run arbitrary code during them. Of course, this doesn't stop compilers from adding their own, which I guess would be more "substages" than stages.
<phoe>
nij`````: stages of working on Lisp code, also known at times
<phoe>
read-time is when code is read; compilation- and macroexpansion-time is when code is compiled and macroexpanded; load-time is when code is loaded; execution-time is when code is executed
<phoe>
there's some other smaller ones, too, but they are only relevant sometimes
<aeth>
outside of EVAL-WHEN + the hyperspec, "execute time" or "execution time" is probably called "run time" or "runtime"
<nij`````>
oh there are so many
<nij`````>
I thought it's only macroexpand + run..
tfb has quit [Ping timeout: 260 seconds]
<phoe>
nope, it's more complex
<nij`````>
Will look into it..
<aeth>
In general, if you can do something at compile time instead of runtime, you probably should, but compilers are probably smart enough to do it automatically most of the time. E.g. In an ancient, non-optimizing Lisp you might do #.(+ 1 2 3) to get 6 (this'll be at read time, not compile time, but it's still doing it in advance) but these days, you shouldn't do that because any decent compiler will turn (+ 1 2 3) into 6
<phoe>
nij`````: most of the time, yes, but these can also happen independently of one another
<phoe>
and compile/load can not be there
<phoe>
because if you load precompiled files then the compile-time is null, it was already done
<nij`````>
Or for example when I'm working with repl?
<phoe>
and if you don't load precompiled files and only e.g. call COMPILE on some forms, hmmmm
<phoe>
does this invoke load-time logic? I don't recall
wsinatra_ has quit [Ping timeout: 258 seconds]
<phoe>
nij`````: it's a bit more involved because usually when you work with the REPL then whatever you type is fed to the compiler and only then executed
<nij`````>
And different cl implementations have different behaviors. Is that correct? Eg. SBCL and ECL might behave differently?
<phoe>
hmmm
<phoe>
I need to re-read this part of the spec
<phoe>
usually the behavior is consistent between implementations
<nij`````>
I see.
KREYREEN has quit [Remote host closed the connection]
<phoe>
and in fact standard CL programmers only need one form of eval-when
<phoe>
namely, eval-always, which is (eval-when (:compile-toplevel :load-toplevel :execute) ...)
<phoe>
everything else is either redundant or completely unnecesssary unless you are writing your own programming language that compiles down to Lisp, or unless you are dealing with the implementation.
<aeth>
yes
<aeth>
in general, you see (eval-when (:compile-toplevel :load-toplevel :execute) ...) when you're defining a function that's directly used in DEFMACRO (rather than indirectly used, by being in the resulting expansion)
<aeth>
You can avoid this if you put it into a separate file that's loaded first, though.
<nij`````>
Woah quite involving.
<nij`````>
I will read that later.
<aeth>
It's actually very basic imo. It really makes macro writing very easy. (defmacro foo (a b c) (actually-implement-the-macro a b c))
wsinatra has joined #lisp
<aeth>
Then ACTUALLY-IMPLEMENT-THE-MACRO is just an ordinary, unit-testable/REPL-testable function that takes in input and returns some lists as output.
<aeth>
It gets complicated if you want it to return advanced objects because then you probably need a MAKE-LOAD-FORM defined for those objects, but in general you'd just be returning things like `(foo ,a ,b ,c) ; that example is so trivial that it shouldn't be its own function
<nij`````>
Oh! That's how many macros are defined? Using functions..
<nij`````>
Why wouldn't one use DEFUN in the first place?
<aeth>
In general, a macro is just quoted s-expressions in, quasiquoted s-expressions out. So the more you move into helper functions, the more straightforward it is
<phoe>
nij`````: evaluation rules.
<phoe>
have you ever tried implementing your own IF using a function?
<nij`````>
NO! I should do that.
<phoe>
yes, please try it before going further
<nij`````>
Great exercise. Implement IF as a macro and as a function.
<nij`````>
Thanks :)
<phoe>
in particular, (if ... (print 42) (print 24)) - check what is printed and check what is returned.
galex-713 has quit [Ping timeout: 272 seconds]
<phoe>
and then figure out why I told you to check those.
<phoe>
just, you know, use the symbol MY-IF instead of IF.
<nij`````>
yep
<aeth>
you can just do this... (%if (lambda () condition) (lambda () if-true-branch) (lambda () if-false-branch))
<nij`````>
Eyes closed
<beach>
Oh, this is "confuse the newbie" time.
<aeth>
But then you could just make an IF macro that does this: `(%if (lambda () ,condition) (lambda () ,if-true-branch) (lambda () ,if-false-branch))
<phoe>
aeth: hey cmon don't cheat
<nij`````>
I won't cheat ;)
<phoe>
let nij figure it out
<aeth>
phoe: I mean, higher order functions make macros unnecessary, but they're not particularly clean :-)
<aeth>
phoe: ah, sorry, I missed the context that you want to see if nij````` can do it
<phoe>
yes
<phoe>
that's the whole point :D
<aeth>
I thought it was rhetorical
<nij`````>
(I'd also like to come back to this point too: higher order functions make macros unnecessary.)
<aeth>
like "good luck making IF a function"
<beach>
nij`````: It isn't true.
<beach>
nij`````: Macros are used mainly to introduce new syntax.
<phoe>
"higher order functions make macros unnecessary"
<aeth>
nij`````: You can do almost everything with LAMBDA that you'd want to do with a reasonable macro (delay evaluation), but it's not going to look clean at all.
<phoe>
that's what java programmers say
<phoe>
and see where they are
<nij`````>
LOL
<aeth>
Macros make it look cleaner, and can even expand to the higher order function
<phoe>
they have 100% of their "functions" and 0% of the clean syntax.
<phoe>
as someone who recently reimplemented the condition system in Java I wholeheartedly hate the syntactical hell that is required to get a simple damn handler-case to work there
<beach>
aeth: OK, so here is a challenge for you. Write a version of LOOP that uses higher-order functions rather than a macro.
<nij`````>
phoe: sad
<nij`````>
Why don't people just use lisp..
<phoe>
yes, that's so sad, alexa play land of lisp music video
<nij`````>
Alexa refuses as it is written in JAVA."
<aeth>
beach: if you let me use dynamic variables (or a hash table!) instead of lexical variables, then it's very doable, but not pretty
<ck_>
I see the backticks have become more plentiful. Are you making progress with your endeavours, nij````` ?
<phoe>
aeth: implement dynavars yourself
<aeth>
ck_: even two `` is a nightmare to remember how , interacts with it
<aeth>
I can't imagine seeing ````` in real code
<beach>
aeth: I think you are missing the point. Macros are used to introduce new syntax. If you are writing something that makes the use "not pretty" you haven't accomplished the task of making the macro unnecessary by using higher-order functions.
<nij`````>
OK I will hide this buffer and focus on writing myfun/if.
<nij`````>
You all are too fun to talk with.
<nij`````>
Bye.
<aeth>
beach: I guess I was unclear. My point is that you can do the same computations with a bunch of LAMBDAs, but the syntax will be uglier.
<aeth>
(It'll also probably be less efficient because the compiler probably isn't expecting code written in this style, but that's an implementation issue.)
surabax has quit [Ping timeout: 258 seconds]
bitmapper has joined #lisp
<aeth>
(Well, I suppose some things, perhaps even with a LOOP-equivalent, would have to interpret some things at runtime that could be done at macroexpansion time, too.)
<beach>
aeth: Two things. 1. There is no such thing as "a LAMBDA" 2. You don't even need anonymous functions to accomplish any computation. Common Lisp is Turing complete without anonymous functions.
<nij`````>
I'm back.... Wait! When writing 'myfun/if, am I allowed to use 'if?
<phoe>
yes
<phoe>
it's the external interface that matters
<nij`````>
LOL I thought one can do it without the special form IF.
<phoe>
it's the fact that it is a function instead of a macro
<nij`````>
That would be awesome.
<beach>
nij`````: Make sure you test it like this: (my-if <some-condition> (print "yes") (print "no"))
<nij`````>
OK lemme keep doing it.
<nij`````>
Sure
<phoe>
I mean, you can do that, but then things become a real hassle
<phoe>
because you dig all the way down into lambda calculus
<phoe>
and that's beyond the scope of this exercise
<aeth>
beach: Afaik, #2 is often only true if you write an interpreter, though.
<beach>
Oh, so a language without anonymous functions can't be Turing complete?
<phoe>
the symbol FOO is a true value, because it isn't NIL, so (if 'foo (print "yes") (print "no")) will work correctly
<phoe>
whereas your won't
<nij`````>
OH deer.
<aeth>
beach: Turing equivalents is only about what they're capable of computing. You're still capable of computing the same amount of things, but there's no guarantee as to the *efficiency* of doing so. I can definitely imagine a language without lambdas, higher order functions, macros, etc., where the only way to get equivalent behavior would be to interpret a sequence of commands and that would still be "an equivalent computation".
<aeth>
s/equivalents/equivalence/
<beach>
aeth: But that is exactly what you said.
<beach>
"My point is that you can do the same computations with a bunch of LAMBDAs, but the syntax will be uglier."
dyelar has quit [Quit: Leaving.]
<beach>
aeth: And I am saying, you can do the same computation without any "lambdas" whatsoever"
<aeth>
Yes, if you don't have lambdas (or good lambdas, in the case of Python) you can still do named internal functions (in the case of Python) and if you don't have that you still have other hacks you can do, and falling back on that you can just interpret a command language or something.
<nij`````>
Sigh. I don't know how to solve the 'foo problem.
<phoe>
nij`````: why even use eval
<nij`````>
because each argument is a list to be evaluated.
<phoe>
wait what
<phoe>
FOO is not a list
<aeth>
beach: My point, which was apparently poorly described, was that lambdas in higher order functions will give you the same functionality of essentially all macros you see in practice. This doesn't mean that there aren't other, even less elegant, ways of doing it.
<beach>
aeth: So now we qualify with "essentially all macros you see in practice". That is very different from "higher order functions make macros unnecessary" which is what I was reacting to.
<aeth>
beach: Higher order functions *do* make macros unnecessary, but they probably don't give you the API that you want and in some cases you might have to resort to dynamic instead of lexical variables. The implicit point in my original statement is that macros exist for syntactic sugar.
<beach>
*sigh* I give up.
abhixec has joined #lisp
gaqwas has quit [Remote host closed the connection]
<cl-arthur>
you can hammer in nails using a very old piece of dry cake, but using a hammer is pretty preferable.
<phoe>
uh guys you are actually agreeing with one another
<aeth>
Although you could put an asterisk by that and say that maybe sometimes the only straightforward way to maintain lexical scope is with a macro...
<jackdaniel>
a keyboard with 0 and 1 do make programming languages unnecessary, because machines interpret binary code
<beach>
nij`````: You were told to test it on something like (myfun/if (= *print-base* 10) (print "yes") (print "no"))
<aeth>
jackdaniel: A better analogy is probably that you can get by with a keyboard that doesn't have a numpad instead of a full keyboard... It's not going to be as nice in every case, but lots of people do it.
<beach>
nij`````: And what was the result.
<beach>
nij`````: You don't test the code by just typing the test.
<phoe>
nij`````: good! now test on (if t 42 (loop))
<beach>
nij`````: You have to run it too.
<aeth>
jackdaniel: Or perhaps "compose key" would be a better keyboard analogy because it really is easier just to type é instead of having to insert the character through some GUI and copy and paste.
<phoe>
and test that with your my-if
<nij`````>
beach: I passed that test too.. lemme include it.
<jackdaniel>
OK, so what? if you use the numpad because you type a lot of numbers, it is worse. do you argue, that a programming language without macros like common lisp is possible?
<jackdaniel>
yes, IT IS :-)
<jackdaniel>
is it possible to type a program on a screen keyboard on your phone? YES
<nij`````>
phoe: UH NOOOOO! I'm suck into a infinite loop :(
<ck_>
how could this HAPPEN I'm not good with computer
<beach>
nij`````: And your tests can't have passed. They must have printed both branches, which is not what you expect from IF, now is it?
<phoe>
nij`````: well
<phoe>
the original IF doesn't loop
<phoe>
(cl:if t 42 (loop)) terminates and returns 42
<aeth>
jackdaniel: Not only is it possible that you should use a language without macros (or, even better, use Common Lisp, but restrict yourself from using DEFMACRO)... you actually should do it for a while. This will motivate you to use and appreciate macros in the future.
<nij`````>
beach: OH you're right. I read the output from the minibuffer, thinking I was right.
<phoe>
agreed, I programmed in Java
<beach>
nij`````: Actually, this is too trivial for #lisp, and perhaps even for #clschool. It should be in #basic-programming-language-facts.
<phoe>
I appreciate macros a lot
<phoe>
beach: that's sorta what #clschool is though
<beach>
I guess.
<phoe>
the difference between functions and macros is not trivial
<beach>
Let's take it to #clschool then.
<phoe>
so I wouldn't call it a basic programming language fact
<jackdaniel>
aeth: I don't understand what you said above. I understand words, but not the whole thing.
<beach>
This is the difference between a function and a special operator, and that is indeed basic programming stuff.
nij````` has quit [Quit: ERC (IRC client for Emacs 27.1)]
nij has joined #lisp
<phoe>
jackdaniel: I understood it as "if you program in e.g. Java for a long while, then you'll get so tired of its inability to abstract away syntax that you're going to really love it when you go back to e.g. lisp where abstracting away syntax is completely normal"
<aeth>
jackdaniel: The point of saying "macros are, technically speaking, not a necessary feature to get things done in Common Lisp" (which is probably what I should've just said) doesn't mean avoid macros entirely. It means, go ahead, try to avoid macros where macros would make sense. Try it. Then you will see why they're there.
<aeth>
s/macros/defining macros/
hydan has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<jackdaniel>
that could be said about many things (i.e calling other functions, or using iteration instead of tagbody); saying that tagbody makes loop unnecessary boils down to saying that you may be a programmer without using physical keyboard
gko_ has quit [Ping timeout: 240 seconds]
<jackdaniel>
technically correct, but that's the worst kind of correct
<_death>
siri, 10 goto 10
<phoe>
(with-siri () (tagbody 10 (go 10)))
<ck_>
_death: :D
<ck_>
"ok, going to 10! going to 10! going to 10! ..."
<aeth>
jackdaniel: I mean, yes. That's a good idea. Do it. Write one program with only TAGBODY for iteration. Every programmer should do it exactly once.
<ck_>
maybe we should put collective effort into program jmc, the digital assistant
<phoe>
actually for very simple state machines TAGBODY is sorta nice
<ck_>
aeth: *macroexpands a loop form*
<aeth>
It's like how so often in math classes they make you do something the slow way before introducing the shortcut.
Codaraxis__ has quit [Remote host closed the connection]
Codaraxis__ has joined #lisp
flavio has joined #lisp
flavio is now known as defunkydrummer
<aeth>
jackdaniel: I think that you think that I think that these programs should be used in production or something. No. They're just exercises.
<aeth>
In fact, exercise 2 after "write a program with only TAGBODY for iteration" should be "now write macros that expand to those tagbodies but don't use preexisting iteration macros"
<aeth>
I mean, it really wouldn't be that bad if you even used non-keywords for extensions and keywords for built-ins since you're probably not going to use many extensions, but there are a ton of built-ins.
lotuseater has quit [Ping timeout: 272 seconds]
jw4 has quit [Read error: Connection reset by peer]
<pfdietz>
I want something where if I load system FOO, and also system BAR, then it automatically loads a system say FOO+BAR needed to make them work together, but that would not make sense if FOO and BAR are not already present.
abhixec has joined #lisp
<phoe>
kinda sounds like an asdf extension?... I mean, new system class, load-op :around method on that system class that checks if other systems are also loaded and then loads their common dependency
<aeth>
That would be incredibly useful for me, but only if it doesn't have to exist in the same .asd file. That is, loading Airship Scheme + loading FOO could load a compatability layer between the two. Which would happen upon loading the second system if the first has been loaded (either order).
<phoe>
aeth: it wouldn't need to live in the same file
<phoe>
the two would need to have some sort of common system class
<phoe>
and metadata stored in either/both systems that allows the custom load-op to load more stuff.
Fare has joined #lisp
aartaka has joined #lisp
<aeth>
phoe: Having one of the two systems have to know about the compatability system with the other is less useful than anyone being able to write a compatability layer, even if it's not officially part of either. There might be some potential for abuse in a wide-open software repository (like Ultralisp?) but not the main Quicklisp dist.
Inline has joined #lisp
<aeth>
phoe: But I think that the most important part would be that the compatability system can be loaded no matter which order the two systems that need compatability are loaded in.
<phoe>
aeth: I mean loading FOO then BAR should trigger loading FOO+BAR on the last load
<phoe>
I mean when loading BAR
<phoe>
same if I load BAR first and then FOO - this second load also loads FOO+BAR
<pve>
there used to be something called asdf-system-connections that may have done something like this
<pfdietz>
That sounds familiar.
<phoe>
"Note: this system is no longer being maintained. Use Quicklisp!"
<phoe>
wait a second, quicklisp doesn't solve this problem
vidak` has quit [Read error: Connection reset by peer]
urek has quit [Remote host closed the connection]
urek has joined #lisp
shifty has joined #lisp
<rpg>
ASDF system connections is morbid and should not be used
<phoe>
uh oh
<rpg>
Note that you could have the FOO + BAR system definition use CHANGE-CLASS on FOO and or BAR to make them be a kind of system that would know to trigger loading of the compatibility layer
<rpg>
I am in the middle of a system update, BTW, so I will be vanishing in a moment, and will lose any responses over the next 10 minutes or so....
defunkydrummer has quit [Ping timeout: 258 seconds]
random-nick has quit [Ping timeout: 258 seconds]
matta_ has joined #lisp
<matta_>
Anybody available to help me decipher an error I get when compiling some code I found on github: Objects of type FUNCTION can't be dumped into fasl files.
<no-defun-allowed>
I don't think there should be a comma before #'or-parser (ditto for #'and-parser)
jpli has joined #lisp
<no-defun-allowed>
Otherwise you would expand to something like (funcall #<function> ...) which isn't easy to dump to a file.
galex-713 has joined #lisp
<matta_>
no-defun-allowed: Thanks, that fixed the compile, and it makes sense since those weren't args to the macro. I'm not even sure what a leading comma applied to a non-arg within a macro really means!
<no-defun-allowed>
It evaluates as per usual.
<no-defun-allowed>
The rules of evaluation do not change in a macro body; look at what `(funcall ,#'cons a b) evaluates to.
tisskenzen has joined #lisp
<matta_>
What is the difference between #'CONS and #<FUNCTION CONS>? I assume #'CONS names the function referenced by the CONS symbol, and #<FUNCTION CONS> is that function?
<no-defun-allowed>
Yes, one evaluates to the other.
<matta_>
Great, thanks! I appreciate it.
<no-defun-allowed>
I don't think there is a benefit to trying to splice in a function object into a macroexpansion.
Inline has quit [Ping timeout: 272 seconds]
<White_Flame>
#'CONS expands to (FUNCTION CONS), which is a form (ie a list of 2 symbols). Anything #<...> is an unreadable object being printed, namely the actual function object here
<White_Flame>
what you return from macros should be source code forms