freenode/#lisp - IRC Chatlog
Search
4:37:45
mfiano
Hello. The spec says that structure-objects may appear in compiled constants if there is an appropriate make-load-form method defined for that type. On SBCL, I get no error with the lack of a make-load-form when defining a constant. On CCL I get the proper error. Can someone explain if this is conforming, or why it is allowed on SBCL?
4:44:31
pjb
mfiano: basically, the problem is that semantically, just saving the slots is not enough. There may be circularities, and there may be other semantic constraints that need to be restored when you read back the object ("hook" it up with the other objects in memory, maintain identity, etc).
4:45:18
mfiano
SInce the standard only allows implementations to define make-load-form specializations for objects of type builtin-class
4:45:25
pjb
It's not against, it's implementation dependent. Conforming programs must provide the make-load-form method.
4:48:41
djeis[m]
The spec specifically says that make-load-form's default method for structure/standard/condition objects throw errors tho.
4:49:02
djeis[m]
So how does compiling a defconstant on SBCL without a make-load-form method work at all?
4:50:19
pjb
Try: (subtypep 'structure-object 'system-class) "It is implementation-dependent whether calling make-load-form on a generalized instance of a system class signals an error or returns creation and initialization forms."
4:51:14
pjb
(defstruct point x y) #+ccl (make-load-form (make-point :x 1 :y 2)) #| ERROR: No make-load-form method is defined for #S(point :x 1 :y 2) |#
4:55:58
pjb
system class n. a class that may be of type built-in-class in a conforming implementation and hence cannot be inherited by classes defined by conforming programs.
4:56:33
pjb
#+ccl (typep 'structure-class 'built-in-class) #| --> nil |# this could be the test to try…
4:57:48
djeis[m]
I think the test would be (typep 'structure-object 'built-in-class), actually. Also nil on SBCL.
4:59:54
pjb
But the definition of system class is informal, so the AFAICS, the implementation could consider structures to be system classes and to provide a make-load-form.
5:00:32
djeis[m]
Yea, but the spec specifically defines methods on make-load-form for structure-object that error.
5:02:06
djeis[m]
Nothing prevents implementations from providing a way to externalize an object that bypasses make-load-form entirely.
5:03:05
mfiano
structure, standard-object: Objects of type structure-object and standard-object may appear in compiled constants if there is an appropriate make-load-form method defined for that type.
5:03:22
djeis[m]
A general-purpose concept of similarity does not exist for structures and standard objects. However, a conforming program is permitted to define a make-load-form method for any class K defined by that program that is a subclass of either structure-object or standard-object. The effect of such a method is to define that an object S of type K in source code is similar to an object C of type K in compiled code if C was
5:04:27
djeis[m]
The spec says that being externalizable is equivalent to having a concept of similarity.
5:05:16
djeis[m]
My guess is that SBCL has a fallback definition of similarity for structure objects that doesn't rely on make-load-form at all.
5:08:45
djeis[m]
Oh, except this last bit: Two objects S (in source code) and C (in compiled code) are defined to be similar if and only if they are both of one of the types listed here (or defined by the implementation) and they both satisfy all additional requirements of similarity indicated for that type.
5:09:50
djeis[m]
And the hyperspec doesn't say it's an error to externalize a structure object without a method on make-load-form, just that you need a method on make-load-form in order to have reliable behavior.
5:11:14
djeis[m]
So now (unless SBCL has documented this somewhere) the reasonable assumption is just that SBCL has some fallback and leave it at that 🤷
5:13:03
djeis[m]
Your quote just says that it must be allowed if there is a method, it doesn't say that it will only be allowed if there is a method.
5:19:17
pjb
Indeed, implementations to be conforming, must document implementation specific behavior.
5:45:16
brainacid0
Hello. Im new to programming in a way. I have played with Linux for 22 yrs. Im 34. Im studying 2HtDP and enjoying it a lot. I have run into some confusions and I hope I can chat with someone. Thanks ;)
5:48:11
brainacid0
Im more of a Super User if you will, rev engineer, not so much as a creator of programs so Im looking forward in learning more but actually connecting with someone I could actually practice with
5:48:57
LdBeth
If you are completely new to programming, I would say The Little Schemer is the best place to start
5:54:14
LdBeth
SCIP is for people who want to know how some commonly seen features in program languages actually work
6:02:28
p_l
mit-scheme, which is pretty much maintained for the purpose of using it for SICP, has its own Emacs implementation (in mit-scheme)
6:49:22
jackdaniel
refpga: maybe something like (mapcar (alexandria:compose #'multiple-value-list #'your-function) list) ;?
6:50:27
pjb
You'd want (multiple-value-mapcar (function truncate) '(10 20 30) '(3 3 3)) -> (3 6 10) ; (1 2 0)
6:51:24
refpga
I just needed to give more than one result for each evaluation. I could give a list out instead of (values) and maybe destrcture that recursively?
6:54:45
pjb
Not efficient, but ok for small lists; (reduce 'append '((val1 val2) (val1 val2) (val1 val2))) #| --> (val1 val2 val1 val2 val1 val2) |#
6:55:27
pjb
works only if the list is less than call-arguments-limit long: (apply (function concatenate) 'list '((val1 val2) (val1 val2) (val1 val2))) #| --> (val1 val2 val1 val2 val1 val2) |#
6:55:39
refpga
Right, perhaps that was what I was looking for. The length of list would be less than 100.
7:27:45
beach
Common Lisp is a general-purpose language that can be thought of as a superset of Emacs Lisp.
7:28:26
hugotty
Well, the gentlemen there quickly pointed out that common lisp was the way to go for a general purpose lisp that was similar to elisp, so here I am :)
7:29:49
hugotty
yes, there's no lack of compilers in the common lisp world, I quickly discovered that :))
7:31:15
beach
Heh. The most common one used by people here is probably SBCL, but your needs might dictate a different implementation.
7:38:03
hugotty
Yes, I've been looking at the different implementations and I've settled on SBCL as well. I was also able to setup quicklisp reasonably easily and SLIME seems to work as expected as well.
7:41:11
hugotty
All in all, setting up a basic common lisp environment wasn't as daunting as I expected it to be!
7:52:24
hugotty
Speaking of quicklisp, I noticed that there were many http client libraries to choose from according to the quicklisp site, is there one you can recommend?
8:01:44
jackdaniel
hugotty: drakma is a popular http client library (it has a good documentation and stable api)
8:32:40
loke
I mean, if you don't need HTTP2 or HTTP3, then Dramka is great, because it is otherwise very complete.
8:38:42
hugotty
I guess I'll have to make due with HTTP 1.1 regardless since it doesn't seem like there even is a http 2 solution for common lisp :p
8:39:08
ecraven
run via fcgi / scgi behind nginx/apache, then you'll get http/2 or maybe even 3 for free ;)
13:16:37
jmercouris
Any way to change the initform of a slot in a class, after the class has been eval'd?
13:17:59
jmercouris
beach: what if I just want to specify that one slot-value? can I use change-class?
13:18:45
jmercouris
the use case, is, a user changing the initform of a slot of a class that they have not defined
13:19:52
beach
jmercouris: If the user did not define the class, the user has no business altering it.
13:20:07
jmercouris
well, I am allowing them to do it, that's the idea, allowing them to customize how the class starts up
13:21:13
jmercouris
okay, here's the very concrete problem: we want buffer specific variables in Next
13:21:44
Bike
global variables are definitely preferable to redefining a class at runtime, which is what you're talking about here
13:22:46
Bike
if you want to let a programmer customize your class what you usually do is let them define a subclass.
13:23:06
Bike
and then you'd want some kind of mechanism so that the rest of the code will instantiate their class instead of your default class, i guess.
13:27:49
heisig
jmercouris: Another option is to add a mandatory 'client' argument to all your generic functions. Its value is initially provided by the user and then passed along.
13:29:45
jmercouris
and then make a thin veneer over defclass to emit global vars for speciallly marked slots
14:40:10
fivo_
Why does (read-from-string "(let ((a '#1=(10 . #1#))) (nth 42 a))") result in infinite recursion and when I evaluate the expression in the REPL it runs fine?
15:27:58
pjb
(read-from-string "(let ((a '#1=(10 . #1#))) (nth 42 a))") #| --> (let ((a '#1=(10 . #1#))) (nth 42 a)) ; 37 |#
15:51:06
sjl_
also, if you're pasting more than 2-3 lines at once, it's generally better to use a pastebin. freenode rate limits so after the first couple of lines they start to slowly trickle in one-by-one
15:51:48
beach
refpga: The forms are evaluated left-to-right, but the variables are bound "in parallel" for LET.
15:57:15
pfdietz
LET* does the binding interleaved with the evaluation, so VAR1 would be visible in FORM2, etc.
15:58:45
shka_
refpga: btw, if you are feeling stressed, inadequate or otherwise uncomfortable at #lisp there is also channel #clshool
16:17:33
fivo_
I am essentially looking for some read function that would return source-line and column
16:17:34
Bike
fivo_: the line and column info is implementation dependent, if that's what you're asking
16:17:57
Bike
https://github.com/robert-strandh/Eclector is a reader library that you can get source info from
16:20:00
Bike
so like (source-line 'funcall)? that's not in the standard (which doesn't mandate implementations be open source, even) but common tools support similar functionality.