freenode/#lisp - IRC Chatlog
Search
4:56:05
kristof
Common Lisp is an extraordinarily good language in this regard. You can get dynamic duck typed languages pretty easily (like Javascript, using a-lists or association vectors of symbols) and you can still share data with statically typed languages
4:56:33
kristof
which simply don't need to do the same type checks that Lisp does. The representation doesn't need to change at all between F# and Lisp.
4:57:08
kristof
These Common Language Runtimes have been proposed for decades because they're really good ideas.
4:57:32
aeth
kristof: Why shouldn't there be one programming language? I'd imagine that in such an environment everything would compile to CL
4:58:23
kristof
Even Symbolics Genera supported at least two different programming languages (Lisp Machine Lisp and Common Lisp)
4:59:32
kristof
I think one of Guy Steele's most important contributions was getting people to understand that there are two things that people confuse: programs, which are abstract, mathematical constructs that "compute", and the languages we use to describe them
5:00:22
kristof
What I'm saying by proposing that the operating system should have a baseline high level language is more like saying that everyone can write whatever programming language they want to target a system that has the denotational semantics of common lisp.
5:01:54
kristof
aeth: Anyway, these are examples of "propositions" that would necessitate a total paradigm shift in conventional operating system design.
5:02:30
aeth
kristof: I think it would be more like CLR or JVM, where it's not like you can program whatever language you want, but that there's an equivalent to Foo as Bar in the runtime.
5:03:19
oni-on-ion
its fun to live in a logical digital world but the analog of change is why we code
5:03:26
kristof
aeth: You can program whatever language you want on the CLR or JVM. They're just machines.
5:04:31
kristof
beach: I hit the "paradigm shift" only recently, when I watched a presentation by a symbolics developer show off Genera. It all clicked, and suddenly I was very impressed.
5:07:13
johnjay
i was browsing his wikipedia and i thought from java to lisp... to parallel C... this is all very broad
5:08:24
kristof
It was from Lisp to Java. Well, to Pizza. Which is not quibbling, because Pizza was notable precisely for the things that were not in Java.
5:08:39
aeth
kristof: What tends to happen in practice is that people program in conceptual ports that interoperate better on the common environment, such as F# on CLR instead of a port of ML or Haskell.
5:09:24
kristof
aeth: In practice, sure. But F# is the way it is because of *C#* compatibility, not because of anything inherent in the CLR.
5:11:03
kristof
I happen to know F# very well, better than i know Common Lisp, so this is sort of my wheelhouse. :P
5:11:04
aeth
kristof: I would suspect that C# compatibility is itself an example of that. The C# built-in things it interoperates with are probably well-optimized.
5:13:04
kristof
The only example I can think of is that the CLR, unlike other garbage collected environments, distinguishes between heap allocated composite datatypes (classes) and stack allocated ones (structs). But that's still a CLR thing, not a C# thing.
5:14:10
aeth
kristof: Since you program in a language with a modern type system... I wonder: What is the CL type system missing?
5:16:28
aeth
kristof: Well what I mean is, I've done some reading on various things that languages brag about in their type system and CL has a lot of direct equivalents, e.g. the maybe type appears to be (or null foo), although that obviously won't work on lists, symbols, or booleans.
5:17:16
aeth
kristof: What can't be expressed well in CL and would it be worth trying to get it into implementations as an extension?
5:17:19
kristof
You know people talk about type safe nullables a lot and they cause more pain than they're worth. The first issue of course is the syntactic overhead.
5:18:34
aeth
kristof: but CL is itself a language where only lists, symbols, and booleans are nullable without (or null foo), at least afaik. And with booleans it really doesn't count because NIL *is* false.
5:19:50
kristof
In fact what I think you mean to say is that "only lists, symbols, and booleans are not trivially nullable in Common Lisp"
5:20:53
aeth
Although if you give a type something (various ways, only CHECK-TYPE and maybe ASSERT being guaranteed) you do have to (or null foo) to permit nil
5:23:28
kristof
Types are important. But what statically typed languages think types are and what lisp, and mathematicians, think types are is totally different.
5:23:45
aeth
kristof: No. I suspect I mix (implementation-optional) static typing and dynamic typing often enough in my CL that neither group would be happy.
5:24:54
kristof
aeth: Have you ever read this? https://groups.google.com/forum/#!msg/comp.lang.lisp/7nhbeh2NIuw/fD-PUkA1yBoJ
5:25:12
p_l
kristof: I think comparing LML and Symbolics CL is a bit of a missm at least on later versions where I think ZL differed mostly in available library
5:26:15
p_l
OTOH, pretty sure the Symbolics C, Fortran, Pascal and Ada compilers all used Lisp as intermediate stage
5:27:12
aeth
kristof: I do write CL sort of like what could be described as "gradually typed", but that's not really a good name for it because there are definitely places where I will never add type declarations or CHECK-TYPE or typed slots or whatever, especially in macros and "gradually typed" sort of implies that you start with T and eventually refine yourself into a Haskell program or something.
5:28:32
kristof
aeth: Sure, I agree, and I would say that the people who repackaged lisp type systems and called it "gradual typing", pretending it was novel, do not intend to fully type their programs, either
5:29:57
kristof
Because static typing is primarily about optimization, not correctness, and optimization is only important in certain places.
5:30:15
aeth
kristof: Repackaged lisp type systems? I hope they included both the numerical tower and multiple kinds of floating point!
5:30:40
kristof
aeth: I remember when Hack came out and they tried to pretend they had done something novel and I thought "this is already on SBCL"
5:31:23
p_l
kristof: arguably Ada's type system is concerned with correctness, not speed (what with subtyping that touches halfway to CL's 'satisfies)
5:31:45
kristof
That's true, and I can't think of any usable programming languages that come anywhere near Ada's type system.
5:34:18
aeth
kristof: this will give a compilation warning in SBCL (and it will compile BAR to always throw a SIMPLE-TYPE-ERROR). (with-compilation-unit () (defun foo (x) (+ x x)) (defun bar () (concatenate 'list (foo 42) "Hello")))
5:34:44
aeth
And if you (setf sb-ext:*derive-function-types* t) then it will always happen, even outside of a compilation-unit or file.
5:35:13
aeth
kristof: So types in CL can be useful for catching bugs early... and I didn't even statically type my example
5:35:45
aeth
But I do have to tell it to sb-ext:*derive-function-types* to make full use of it because it violates the ANSI standard iirc
5:36:35
aeth
(That variable tells it to assume that function types will not be redefined even when functions are redefined, which allows the compiler to make more assumptions.)
5:37:05
kristof
aeth: That's good, but do you think you never would have caught that bug if you didn't have static typing there?
5:37:41
aeth
kristof: I would have caught it in the middle of executing the program. FOO and BAR might be very far apart, and that runtime error might happen rarely, or after a long time.
5:38:06
kristof
You would have caught it in the middle of executing the *line*, not necessarily the whole program.
5:38:35
aeth
I like it when things fail early, especially if it's running in a program that has to CFFI, which can make debugging less fun.
5:38:40
kristof
line coverage also solves the problem of "I don't know when this might be triggered." Go on and trigger it yourself!
5:39:13
kristof
aeth: When I hear this argument for (completely, not gradually) statically typed languages, I like to compare it to spellcheckers
5:39:39
kristof
I think there is a set of things that I would want to check for when I write an essay. I think spelling is a good one, and it's also an easy one. I think there are many more ipmortant things, though, than spellchecking.
5:41:10
aeth
If I don't know how to spell a word, I just type it into *scratch* as "foo", i.e. as a string, so flyspell-prog-mode catches it
5:41:31
kristof
He or she specifically asked me "What do you thinks Lisp's type system is missing that other languages have", and I countered that it's other languages that should adopt Lisp's more general, more useful type system.
5:44:47
aeth
kristof: I'm still wondering what I'm missing in a typed slot, e.g. (defstruct foo (name nil :type (or null keyword))) ; it's unfortunate that :type, while optional in both, is respected in defstruct more than in defclass... I actually have a metaclass that enforces a type check portably on a slot
5:46:33
aeth
When I want to rely on a type check, I use a metaclass that has a :checked-type arg that does this: https://gitlab.com/zombie-raptor/zombie-raptor/blob/e404e51d899b45808e6fc4b7af281861073892a1/util/util.lisp#L536-543
5:47:25
aeth
kristof: Yes, where it does not check types and you can set it to whatever you want in a writer or in a constructor
5:48:30
aeth
I cannot assume that my users will use higher safety levels, especially because I am writing a game engine, where the focus will be on performance. But I do try to use the type system to ensure that I'll catch bad input as early as possible, and in Lisp rather than when feeding it to the CFFI (which is necessary for a 3D game, unfortunately)
5:50:23
kristof
Yeah, I would have expected default safety and speed levels to warn on provably bad input
5:52:00
kristof
In a game engine I would expect there to be a *lot* of type directed dispatch though, right?
5:53:03
kristof
I would imagine there's a fair amount of difficulty when it comes to type propagation and CLOS but I don't want to speculate.
5:54:08
aeth
kristof: Not at the moment. I'm still working on the optimized core (it's not really premature optimization, this is the stuff that's run 60 or 100 times a second in a hot loop at the core of everything else)
5:54:51
aeth
There are some higher order functions already, though. Where those make sense. I think at the moment that's input and scripting
5:55:22
aeth
(Maybe it's not wise as far as performance goes to funcall items from an array for all of the input, but it's just too convenient.)
5:55:53
aeth
(And I funcall 'foo, not #'foo, so I can have them recompiled. Not sure if that would hurt performance even more. But, again, a necessary evil.)
5:57:35
kristof
aeth if you're worried about performance I'm actually quite surprised you funcall a symbol :P
6:01:01
aeth
ldb: Well, I guess an alternative to an array might be to make it a several hundred line CASE, but I doubt SBCL optimizes for that. Still might be faster, though.
6:01:05
kristof
The correct thing to do is to define your own reader macro, or perhaps redefine #', so that in dev mode you get (quote foo), and in release mode (function foo)
6:06:55
aeth
kristof: redefining #' might actually be the way to go, although I would have to make sure that anywhere where I have CHECK-TYPE or :TYPE etc I use (or symbol function)
6:07:29
aeth
I suspect I already have type 'bugs' like that in my engine. I should probably define (or symbol function) as a type.
6:15:05
aeth
Is (or symbol function) the correct type for funcallable things here? I think MOP adds funcallable instances, but I don't think they'd be used in this context. It looks like adding symbol as a possibility adds one test, so it probably won't hurt performance in a noticable way.
8:12:09
shka_
is change-class guaranteed to change existing instance instead of allocating and returning new one?
8:14:00
beach
For example, in SICL, every standard object has a header and a "rack". The header contains a (pointer to a) class and a (pointer to a) rack.
8:20:49
aeth
shka_: everything's boxed except for things smaller than 64-bit (assuming a 64-bit implementation). That's probably single-float, fixnum, symbol, keyword, maybe character. Definitely implementation-dependent. Fixnum has tag bits, possibly just one (like in SBCL, which makes it a (signed-byte 63)). single-float is obviously half of the size so it definitely fits (for 64-bit implementations).
8:21:50
j`ey
when (time..) on sbcl shows N bytes consed, I assume that's also talking about boxed things?
8:22:23
shka_
you don't have pointer to storage area, you have pointer to pointer to storage area :-)
8:25:03
beach
Though symbols would not need any indirection since you can't change the class of a symbol.
8:26:51
givre
Hi, i'm trying to build a macro to pass a bunch of functions to a cond statement. I've tried the following to no avail : (defmacro find-element-with-multiple-strategies (value l (&body strategies)) `(cond ,@(find-element ,value ,l #'strategies)))
8:27:52
beach
First COND is a "form" not a "statement". Then, how do you pass a function to a COND form?
8:28:28
beach
givre: I suggest you use a pastebin to show your code, but also what you expect from the expansion of your macro.
8:29:14
beach
givre: It would also be very unusual to have &body wrapped in a sub-lambda-list the way you did.
8:29:34
givre
beach: I want to unwrap the list of strategies to build a cond form containing all the functions
8:30:10
givre
beach: yeah that's what i figured, i'm not really familiar with macros, i'm going to post the code on pastebin + expansion
8:31:38
beach
givre: Also, when you do #'strategies, you are looking in the function namespace and not in the variable namespace.
8:32:12
shrdlu68
shka_: I've been thinking about that too. Using hash tables, at least as I currently use them, is untenable.
8:35:24
shrdlu68
shka_: What did you make of sb-sprof's output? Hashtables apparently aren't the bottleneck.
8:36:46
shrdlu68
shka_: I've also been thinking about implementing bit vectors in octet vectors with a little bit of overhead, but this is apparently exactly how SBCL does it.
8:37:07
aeth
(The HyperSpec says that "the actual internal representation of symbols and their attributes is implementation-dependent", but there might be a common implementation technique.)
8:37:09
beach
givre: ,@(find-element ...) will call the function FIND-ELEMENT and insert each element of the list that it returns.
8:37:24
shrdlu68
shka_: Does it account for the supermassive performance difference between SBCL and other implementations?
8:40:31
shka_
shrdlu68: i can't check right now, but it is possible that CCL does not like bitvectors as keys in hashtable so much it generates to O(n) lookup
8:41:42
shka_
simply populate hashtable with bitvectors measure time, populate hashtable with twice as many bitvectors, measure time again
8:43:49
givre
beach: honestly don't understand all the meaning of #' right now, so would be able to tell you why. I'm trying to abstract away the use of a cond, I want to be able to search in an assoc list with multiple matching strategies (right now i'm splitting a mail adress and matching user login with the first part of the mail for instance)
8:45:14
beach
givre: OK, but it is not going to be possible for you to write a macro unless you first know what ,@ does and what #' means.
8:48:06
beach
givre: But, you seem to think that it expands to (cond (list ...) (list ...) (list ...))
8:50:07
givre
beach: sorry, i meant the cond clause is not a cons. Yeah that's what i did obviously. It expands to (cond 1 2 3 234)
8:50:48
beach
So, why do you think your expansion will contain (find-element when mine doesn't contain (list?
8:53:14
givre
beach: I believed that placing the ,@ before a form instead of the parameter would splice differently, which is far fetched yeah
8:53:27
beach
givre: Like I said, ,@ will evaluate the form that follows, in my case (list 1 2 3 x) and then splice the elements of the resulting list into the COND.
8:59:25
givre
givre: the find-element function is awaiting a function parameter, i passed it this way and then applied it in the body when i was not using the list
8:59:41
beach
givre: I suggest you write a function that returns the list ((find-element 1 '(1 2 3) (lambda ...)) (find-element 1 '(1 2 3) (lambda ...))). Once you have that, you can stick a call to it after the ,@ in your macro body.
9:00:47
givre
beach: I guess for the #' I don't need to use it because my lambda will be #'ed in their list anyway right ?
9:02:00
beach
There are "functions" and "lambda expressions" (which are not functions, but code), so again, it depends.
9:06:37
beach
givre: Here is a better example: Consider the macro (defmacro baz (x y) `(list ,x ,y))
9:07:48
beach
In the first case, you are passing lambda expression to the macro function, because macros do not evaluate its arguments.
9:08:13
beach
In the second case, the reader will create functions for you and those will be passed to the macro function.
9:11:11
TMA
givre: to macroexpand is to call MACROEXPAND on the (quoted) form, not to _run_ it (possibly call MACROEXPAND-1 to look at one level of macroexpansion at time)
9:12:32
aeth
You usually want macroexpand-1 because macroexpand will leak implementation details as it keeps expanding well past the standard forms
9:13:29
beach
It is just amazing that you are trying to write a macro this early in your Common Lisp training.
9:14:51
beach
givre: So with all this information, you should be able to write a better version. But I this is too basic for #lisp, so next time you need help, I suggest you visit #clschool instead of #lisp.
9:15:43
givre
beach: i've been doing a bit of common-lisp for times to times over the past few years, but right now i've got the opportunity to write some POC at work and real code so here am I
9:16:09
shka_
givre: there are multiple ways to implement such functionality, and macros have major drawbacks
9:17:53
aeth
I recommend people stick to established patterns when learning how to write macros. DO-FOO, DEFINE-FOO, and WITH-FOO are all simple and are the vast majority of macros you'll probably see/write
9:19:02
givre
shka_: ok, i was about to ask for betters leads. higher order functions are something I can relate to a bit more indeed !
9:22:02
shka_
anyway, contrary to what many would say, you can spend whole day in CL without defining your own macro
9:28:29
givre
shka_a: Sure ! I'll write this macro anyway since I invested time in it, then I'll stick to actually writing code.
9:31:48
Demosthenex
so i have a simple http api to postgres project i'm doing, i'm considering threads to run requests in parallel. i have no global or shared variables, other than potentially postmodern's db connection and dexador's. i'm reading on bordeaux threads, any other suggested reading?
9:37:44
shka_
Demosthenex: lparallel is thread pool, futures, some paralleized higher order functions, sync queues and some other stuff
9:39:53
Demosthenex
i think this is a simple job and a good fit for parallelism... so i'll give it a go
9:46:39
makomo
i was scrolling through SBCL's sb-walker codewalker and stumbled upon this comment https://github.com/sbcl/sbcl/blob/master/src/pcl/walk.lisp#L393
9:47:48
makomo
implementing special forms as macros should be conforming afaik, but does the same hold for the reverse?
9:51:45
beach
"An implementation is free to implement a Common Lisp special operator as a macro. An implementation is free to implement any macro operator as a special operator, but only if an equivalent definition of the macro is also provided."
9:54:13
Demosthenex
shka_: give i know how many pages of data i'm downloading, i'm thinking of just using pmap
9:55:39
makomo
beach: so for the purposes of a code walker, one can just ignore the fact that a macro is implemented as a special operator when there will surely be an equivalent definition of the macro
9:57:22
makomo
beach: mhm. the "codewalker problem" is quite an interesting one, and i always wonder how useful would a codewalker within the standard be
9:58:35
pjb
makomo: or in a library, no need for a standard. The only thing, would be that implementation don't have macros that expand to non-standard special operators that don't have a macro expanding only to standard operators.
9:59:19
makomo
i've watched michael raskin's talk on a portable codewalker, and from what i've seen, doing it portably isn't really possible
9:59:37
pjb
beach: the implicit in "but only if an equivalent definition of the macro is also provided." is that this macro expands to standard special operators…
10:00:22
beach
makomo: So for those parts, come up with a CLOS protocol so that implementations can configure it.
10:00:43
makomo
beach: mhm, i get your idea, but it would still be nice if it could be done 100% portably
10:01:54
makomo
i think i have a vague idea (i forgot much of the talk) -- it might have something to do with environments
10:02:36
makomo
but, reasons for it not being possible aside, i would still wish that it could be done portably
10:03:51
beach
The problem is that the implementation may call MACROEXPAND on a lexical environment.
10:08:36
makomo
beach: reading your code walker specification that i just found -- good stuff! a minor typo: "and interpreter" https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Code-walker/Specification/code-walker.text#L70
10:10:53
makomo
beach: i think christophe's post was about "let over lambda", not "land of lksp" (assuming we're thinking of the same article) https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Code-walker/Specification/code-walker.text#L15
10:11:09
pjb
beach: I don't think a code walker should expand the standard special operator as macro ever.
10:11:14
makomo
here's the post about code walking: http://christophe.rhodes.io/notes/blog/posts/2014/naive_vs_proper_code-walking/
10:16:53
makomo
j`ey: a program that knows how to "interpret" common lisp code and that can tell you various stuff about it
10:16:56
jackdaniel
since body contains code, such macro has to understand meaning of special forms, macros, functions, variables etc
10:17:10
makomo
"interpret" not in the sense of executing it, but in the sense of "walking" it and "figuring out what the code does"
10:18:51
jackdaniel
since code walking is non-trivial in common lisp it is hard to get right (hence it is rarely used in "normal" applications)
10:23:33
pjb
beach: Yes, https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Code-walker/Specification/code-walker.text#L98
10:24:12
pjb
The code walker should not always try the macro first. If it's a special operator, it should call the user function with it, and let it interpret the special form.
10:25:20
makomo
beach: ah :-). i suppose this text will eventually become part of the main SICL spec (the collection of tex/pdfs you maintain)?
10:25:21
pjb
beach: now, there may be an option to do what you specified, but in general, I wouldn't use it.
10:25:48
makomo
beach: "during during" https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Code-walker/Specification/code-walker.text#L63
10:26:09
beach
makomo: Possibly. Since I couldn't remember having written it, it might have been forgotten.
10:26:30
makomo
beach: "body code" ("body of code" perhaps?) https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Code-walker/Specification/code-walker.text#L79
10:26:48
pjb
The thing is that such special operator macro will most certainly do implementation specific things, such as ignoring ignorable special operatorns (eg. THE). A code walker will usually want to be conforming and extract the semantics of the program in an implementation independent way.
10:27:49
makomo
the thing about not trying macros first is also mentioned in the comments of sbcl's walker https://github.com/sbcl/sbcl/blob/master/src/pcl/walk.lisp#L389
10:39:27
makomo
beach: "a code walker (...) that collect (...)" https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Code-walker/Specification/code-walker.text#L112
10:41:52
dim
as with many things in CL I though it was somewhat overkill until I had a use for it ;-)
11:23:07
jackdaniel
Xach: CG memos you've shared the other day by Alvy Ray Smith are true gems, thank you again for sharing the link
11:32:05
Xach
jackdaniel: many years ago i ran a GIMP web forum and he joined and asked if gimp was making the mistake of being rectangle- and square-centric with regard to images and layers, and a few deveopers chimed in that those were the most natural and anyway image formats are all square, and who are you, anyway, old man
11:32:20
Xach
jackdaniel: it was pretty embarrassing when i saw him in a pixar documentary and he was a founder
11:33:59
jackdaniel
truth to be told, orbitrary shapes/ transformations for various objects make my life certainly worse than it should be (mcclim-wise)
11:34:53
Xach
right - his notion is to break free of tradition and ease - kind of like how gc frees you, even though making gc work is difficult
11:34:56
jackdaniel
and it is just in time I've read it, because next biggish thing I want to add to mcclim are animations
12:48:32
oni-on-ion
aeth: are you still awake or up yet? what did you mean earlier when you said that funcall happens differently on 'foo than #'foo ? i think that might be part of a problem i ran into last nacth
13:13:08
EvilTofu
Moo. I've just downloaded CCL 1.11.1 from the Apple Mac App Store. HyperSpec look ups just give me a Map_Sym.txt file not found dialog. Is there a fix for this?
13:14:30
oni-on-ion
never heard of that before. i myself use slime in emacs with HyperSpec downloaded from lispworks.com and the help lookups (C-c C-d h) are great
13:21:27
oni-on-ion
aeth: ah it did solve my problem! i've got to learn the difference between #'foo and 'foo now.
13:33:41
pfdietz
"Because static typing is primarily about optimization, not correctness, and optimization is only important in certain places."
13:38:47
oni-on-ion
for me, types help to design data structures, which helps to plot and plan - where most i guess use paper or their own heads
14:26:51
oni-on-ion
slime-highlights is really great. make changes anywhere, they are highlighted, C-c C-c to compile those
14:34:57
oni-on-ion
could we use setf places in let forms? ie. (let (((slot-value h 'conn) (make-connection..))) ...)
14:38:47
trittweiler
oni-on-ion, search for LETF. It used to be provided on the Lisp machine. And implementation based on setf + unwind-protect is easy, but it doesn't really work well in multi-threading environment (contrarily to LET, both for lexical bindings (trivial) and dynamic bindings)
14:39:25
oni-on-ion
trittweiler: ohh,i thought that letf was for functions on just the right hand side only =)
14:40:06
trittweiler
there's also an implementation of lets in Emacs' cl implementation. Probably can just take that. Or search comp.lang.lisp
14:56:27
schweers
I have a hopefully quick question. I don’t indend on doing this, partly because I don’t know how. I just want to know a) if it could be done, and b) whether that would be considered sane. Suppose I want to place very simple datastructures (for the sake of argument, lets say something like a defstruct) in a specific place in memory, like a memory mapped file or shared memory, or something similar. Can the MOP be us
14:57:27
Xach
oni-on-ion: if it's (defmethod frob ...) you would inspect the #'frob generic function, and slime shows a list of methods with options to remove
14:57:49
oni-on-ion
https://github.com/robert-strandh/CLIMatis/tree/master/Applications/Clouseau <-- ah there is !
15:05:16
oni-on-ion
hey so. how come (slot-value h :conn) does not work, but (slot-value h 'conn) does -- when defclass slot was set to :initarg :conn ??
15:05:40
Xach
oni-on-ion: the :initarg is the symbol used in make-instance, not the name of the slot.
15:09:25
Xach
jasom: I am trying to build a cuda library and i don't care if it really works, i would just like a (possibly non-working) .so to see if I can make progress.
15:23:10
pjb
mkdir -p ~/quicklisp/local-projects/com ; cd ~/quicklisp/local-projects/com ; git clone https://github.com/informatimago/lisp.git informatimago
15:24:02
pjb
But it counts only from the time loaded, so you have to insert this (ql:quickload "com.informatimago.common-lisp") in your rc file.
15:59:34
makomo
if i want to communicate that a slot should be initialized to the empty slot, should i use :initform () or :initform '()
16:04:44
shka_
I think that in the case of slots, it is beneficial to supply :type option in order to be more explicit about your intents
16:06:06
pjb
(mapcar (lambda (other-nil) (eq nil other-nil)) (list nil () 'nil '())) #| --> (t t t t) |#
16:06:40
makomo
mhm. misunderstood what you said there (thought you weren't talking from a style standpoint)
16:07:36
beach
(let (a b c) means a b c are "uninitialized" so the person reading your code expects them to be assigned to before being used.
16:09:09
pjb
There's notably the case of (let (a) (declare (integer a)) (setf a 42)) ; technically before the setf, reading A would be a bug, since we would read NIL as an integer!
16:10:05
pjb
But it does, because lexical variables cannot be unbound. and local dynamic bindings must shadow the outer dynamic binding.
16:15:15
makomo
beach: we've discussed this before and you also mentioned it yesterday again -- using accessors internally instead of directly using slots. then, if one wants the client to actually use some of those accessors, one should export the respective symbols, right?
16:15:40
makomo
beach: but what about when you want to export e.g. only the reader, and not the writer? this isn't really possible, is it?
16:16:21
Bike
i've a few times had ":accessor %foo :reader foo", defined a special (setf foo), and then exported foo and not %foo
16:16:28
makomo
oh, good point, didn't think of that. what would be the canonical names then? %something?
16:18:46
Xach
beach: sorry. i misread as :writer %foo, which can be confusing, because plain functions don't often use setf argument style.
16:19:13
Xach
when i first tried separate :reader and :writer, i thought :writer foo would create (setf foo)
16:19:21
Xof
if you do that because you don't want users to mess with slots, you might also want to make sure that your initarg(s) isn't/aren't exported
16:19:41
Xof
otherwise users will defeat your protections by using (reinitialize-instance object :%bla 3)
16:19:57
pjb
pfdietz: stylistically, it would be bad. But notice about arrays, that if no :initial-element or :initial-contents is given, the memory is not initialized so you could get mis-interpretation of the bits, and the standard only says: "don't do that".
16:21:35
pfdietz
The standard pretty explicitly says the declaration has to be in effect right after the binding occurs, even without an explicit reference by the user. Look up bound declaration and declaration scope. Undefined behavior if not the right type.
16:23:38
beach
Xof: I had an interesting phone meeting with Didier Verna today about my solution (in SICL) to method combinations. He seems to think it is sound, so there might be a joint ELS paper submission at some point.
16:24:41
Bike
pfdietz, pjb: clhs type says initial values of the variables have to be of the type. seems straightforward.
16:24:57
spm_
I'm having a little trouble understanding how quoted lists get applied as default &key arguments. I thought the list would be passed fresh to each call of a function, but the list seems to persist across calls. Clearly wrong-thinking on my part, but I'm not entirely clear why.
16:26:32
pfdietz
The user has not given an explicit value, but the standard says what the value is. It's NIL.
16:27:28
pfdietz
"3. At the moment the scope of the declaration is entered, the consequences are undefined if the value of the declared variable is not of the declared type. "
16:27:34
spm_
Xach: Thanks. Yes, I figured out how to not have the problem, but am not clear regarding in-what scope the quoted list becomes defined, and what happens on subsequent calls to the function.
16:27:46
pjb
spm_: the init-form is evaluated at call-time, only if no matching keyword argument pair is given.
16:28:06
Bike
spm_: nothing to do with &key. you are editing quoted data, which is always undefined behavior.
16:28:36
pfdietz
"The scope of a bound declaration is the same as the lexical scope of the binding to which it applies; [...]"
16:29:07
pjb
spm_: so the question is whether you want the same list or a new list each time: https://pastebin.com/sz43meDi
16:29:47
Xach
sbcl can be quite helpful with warnings about modifying quoted/literal data, but it doesn't catch everything
16:32:49
spm_
pjb: Yes. new value each time was what I was after, and not what I was seeing. My thinking was that a new quoted list would be created each time the function was entered if it wasn't provided.
16:35:07
Xach
spm_: possibly because someone could pass a keyword and the warning wouldn't apply...not sure.
16:35:57
pjb
(defun f (&key (x (error "You need to pass a :x argument!")) y) (list x y)) (f :y 42) #| ERROR: You need to pass a :x argument! |# (f :x 42) #| --> (42 nil) |#
16:36:31
spm_
Thanks for the assist. I need to do more reading on compile/init of functions as the "why" still isn't fully clear to me, but if the behavior of modified quoted literals is undefined, then I certainly ought not do that. :-)