libera/#commonlisp - IRC Chatlog
Search
6:10:11
moon-child
'Prima facie these are all candidates for adding type-error for each wrongly typed argument' barring constructors and predicates, and a couple of other fun ones like constantly
6:15:42
spiaggia
By "barring", do you mean that they are not (yet) on the list, or that they are and they shouldn't be?
6:21:51
phantomics
Hi, a question. I can't create subclasses of built-in CL classes like simple-array, so is there any other way of creating an array that has some specialized metadata that it carries with it but which functions as a standard array in all other respects and can be arefed and measured without the code doing so needing to be aware of its special type?
6:24:22
hayley
You could put the metadata in a weak hash table, but of course that is not in the array, and it is not reflected in the type system.
6:24:56
phantomics
That's what I've been doing, created a big hash table whose keys are the actual arrays I'm keeping track of
6:28:08
flip214
phantomics: you could have a few reserved elements in your array - eg. at the beginning. (Perl would allow to specify a negative start point for the indizes; CL doesn't, sadly.)
6:28:13
moon-child
I thought you were still not going to allow user code to subclass them, for portability reasons?
6:29:17
phantomics
flip214: the problem with that approach is that I want these arrays to be usable with any old CL code outside the system without someone having to make special allowances
6:29:32
moon-child
Hm. I thought you had said you were going to add a special-case to prevent that. I must be misremembering
6:30:52
phantomics
Currently, the arrays April generates are completely standard Lisp arrays, you can aref them, take their size and dims like any other array. If I wrap the contents in another array structure containing metadata it'll defeat that purpose, I might as well create a special class containing the array and its metadata at that rate
6:31:26
spiaggia
moon-child: In fact, I think it would be a good idea to expose the mechanism by which I create specialized arrays, so that someone who wants an array of (say) 24-bit integers can do that. It is basically a matter of defining the transformations CST-AST-HIR-MIR and associated classes.
6:32:44
flip214
phantomics: you could make the visible array displaced, and keep the metadata in the array the visible one is displaced to
6:32:45
phantomics
moon-child: I want to store something called the "array prototype." This sounds very strange, but an APL array will "remember" what its first element was if you shrink it to size zero, and if you then take that 0-size array and do a larger take of it, it'll reproduce its first element
6:32:49
spiaggia
moon-child: And, the SICL code should also be structured this way in fact. Currently, that's not the case.
6:33:09
flip214
but that makes a bit of difference - performancewise, and what you can do with that (displaced) array
6:33:59
phantomics
moon-child: if an array's first element is an array itself, the prototype will be an array of the same composition but with all its values set to the default for its type, like blanks for characters and zeroes for any other type. Hopefully that makes some sense
6:35:56
phantomics
moon-child: so for a 20x10 array with metadata, I could have the base array be a 201-element vector with the first element containing metadata, and then there would be a 20x10 array displaced to it with an offset of 1?
6:38:02
phantomics
If I have a fill pointer my understanding is that the (array-size), (aref) and other functions will still be aware of the array's full size, my goal is to have something that behaves just like an array for an external system that receives these arrays but has some special metadata
6:38:18
moon-child
though note for certain higher-rank array operations it is useful to pad the shape to have some alignment
6:40:53
phantomics
Ok, that could work, so you're suggesting create an extra row for the "parent" array, the first element would be the metadata and the rest of the element would be blank
6:41:44
phantomics
Although the thing is, all arrays that need this metadata are necessarily empty, like (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (0 0 0))
6:44:27
flip214
phantomics: well, then declare (deftype my-array-prototype () T), and when an array should be empty it actually contains 1 element, with that type.
6:44:51
flip214
so, by checking the :element-type, you can see that an incoming array should be treated as empty.
6:45:52
flip214
basically, use the element-type of an array to store _whether_ it is special - and then it may contain arbitrary data.
6:46:07
flip214
makes it even non-displaced, and not needing a fill pointer - both good for performance.
6:46:15
spiaggia
flip214: Are you assuming that ARRAY-ELEMENT-TYPE returns whatever you used when it was created?
6:47:12
phantomics
Because the prototype of the array is an array itself, i.e. #2A((0 0 0 0) (0 0 0 0) (0 0 0 0))
6:48:06
flip214
well, you can also define a structure that contains the prototype - and have that as element-type for empty arrays.
6:48:41
flip214
phantomics: (defstruct my-empty-array-type (prototype)) (make-array 1 :element-type my-empty-array-type)
6:50:29
flip214
another idea: only when empty, the array is displaced - to another array, whose elements contain the dimensions and/or type
6:52:04
phantomics
I only need to collect this data for empty arrays that were reduced from an array with an array as its first element
6:52:25
phantomics
So when that is done, I'll create a 0-size array that's displaced to a 1-size vector whose element contains the list of metadata
7:00:15
flip214
it might be more convenient to have a non-displaced array with a :fill-pointer 0 and size 1, with the prototype in index 0. perhaps there's a performance difference for array-has-fill-pointer-p vs array-displacement.
7:01:37
moon-child
empty arrays are likely to be the exception rather than the rule. And fetching the prototype is a constant overhead in any case. I don't think optimizing heavily for that case is worthwhile
7:06:36
phantomics
Yeah, the logic will be 1) is the array empty? 2) is it displaced? 3) get the displaced-to array and check for valid metadata
7:07:08
phantomics
This is a corner case and one of the stranger things about APL's array model, the only aspect that can't be neatly reproduced in CL
7:14:10
phantomics
That's the trouble with CL... if you want to break from convention you open the door to a host of compatability problems
7:15:04
phantomics
If you want to add new features to the language, yes, that's what drove fare to Gerbil Scheme
7:15:18
moon-child
you're using cl to make an apl implementation. No apl implementation is compatible with any other anyway, so I don't see the problem?
7:16:23
phantomics
I could just leave array prototypes out but it's an accepted feature of the language, there's some interesting code out there that uses them
7:17:22
beach
Yesterday, we heard that Common Lisp is bad because it has a standard, and today we hear that Common Lisp is bad because it is strict about conventions.
7:18:06
moon-child
can't you just make everything use prototype 0? I can't imagine there's _very_ much interesting code using characters or nested arrays in a way that that would matter for
7:19:18
phantomics
The Schemes all have discordant features, choosing one is taking a major gamble that it won't fall out of favor. The Racket devs seem to want to move it away from being a Lisp entirely
7:19:39
shka
pl: pythonists seem to have a slavish mentality so i my bet is that it is not one of those :P
7:20:39
pl
shka: Python is also one of the few languages that /explicitly/ go out of their way against standardisation. Maybe Rust too, but most other stuff has some level of standardisation even if it's not fully formal static one
7:20:39
phantomics
moon-child: I can easily have the array default element be either " " for character arrays or 0 for all other array types, I can deduce that from an array's type
7:21:29
shka
pl: sure, but the typical python programmer is just all over the every little detail of python guideline
7:21:40
phantomics
The array-as-prototype is useful in a few cases, I've ported some functions from Dyalog that use the feature to do interesting things
7:21:52
pl
phantomics: CL being mostly compatible between implementations (and nearly to the point of irrelevance when you add portability libs) is what finally got me good on Lisps :)
7:23:48
phantomics
The (0⍴⊂_)from 99 is a particular case of using a displaced array, the 0⍴ creates an empty array whose prototype is the "_" variable defined earlier
7:24:53
phantomics
The idea of being to create arbitrary-shape nested arrays from with a prototype array element is useful for a few things
8:49:14
pve
phoe: Hey, you mentioned yesterday that "the reader macro for #\( cannot call READ-DELIMITED-LIST directly". Can I read more about this somewhere?
8:55:16
beach
pve: I think phoe is just making the observation that READ-DELIMITED-LIST has no provisions for handling the consing dot.
8:59:22
pve
on CCL I get: (with-input-from-string (s "a b . c)") (read-delimited-list #\) s)) ==> (A B . C)
9:04:53
pjb
Indeed, the lisp reader algorithm and specifications of the reader macros imply that the reader macro for #\( cannot use the standard read-delimited-list.
9:05:45
pjb
pve: note: #(a b c) could use read-delimited-list. But ccl uses a ccl::read-list in that case :-P
9:06:36
pjb
The algorithm of read-delimited-list is specified: read-delimited-list looks ahead at each step for the next non-whitespace[2] character and peeks at it as if with peek-char. If it is char, then the character is consumed and the list of objects is returned. If it is a constituent or escape character, then read is used to read an object, which is added to the end of the list. If it is a macro character, its reader macro function is
9:06:36
pjb
called; if the function returns a value, that value is added to the list. The peek-ahead process is then repeated.
9:07:59
phoe
pjb: now I am longing for a publicly exported and available CCL::READ-LIST, why did you mention it out loud
9:09:35
pve
although, I should admit, I don't quite see *why* the specification implies that read-delimited-list can't be used
9:21:25
phoe
CLHS 2.3.2.2 - "An implementation may provide one or more kinds of float that collectively make up the type float."
9:22:33
phoe
(it's probably a nitpick from my side, I just looked at this passage and got both confused and amused)
9:40:04
pjb
there are only a small constraint on where to split the floats when you provide only 2 or 3 float types.
9:41:05
pjb
Note also about floats, it means most typecase trying to dispatch on float subtypes are not conforming!
9:42:41
pjb
https://github.com/informatimago/lisp/blob/master/common-lisp/cesarum/utility.lisp#L1261
9:42:41
pjb
https://github.com/informatimago/lisp/blob/master/common-lisp/cesarum/utility.lisp#L1380
9:43:34
pjb
beach: Well, non-conforming is perhaps too strong a word. The problem is that (typecase foo (single-float 1) (double-float 2)) may list two identical types. It will make compilers generate code about unreachable code (eg. 2).
9:44:50
pjb
The docstring of distinct-float-types quotes the small constraints on how to split the floats when fewer than 4 types are provided.
10:19:31
mrcom
pjb: Weird crashes I was getting in CCL on OSX have stopped. Which is even weirder. Didn't update anything.
10:59:55
nij-
Swank.lisp has ~4000 lines of code, much for a newbie like me. Could someone confirm that it implements socket/connection by itself, making no use of any networking library like usocket or trivial-socket? https://github.com/slime/slime/blob/master/swank.lisp
11:03:59
nij-
Yeah.. I'm thinking if it's possible to factor the socket part out, making it easier to support other protocols.
11:05:52
nij-
Xach: Thanks for your confirmation. And yes, if they switch to usocket, the amount of codes could be largely decrease.
11:08:31
pl
nij-: the issue is that you want swank to run self-contained so that you can just start it on any supported implementation without external dependencies
11:10:31
nij-
That makes sense. I feel that being orthogonal and being self-contained are two good attributes that contradict to each other.
11:19:48
shka
swank does not support encryption or logging so it's only natural that localhost is only allowed
11:28:29
nij-
shka: My apologies if the following is too simple: Does that mean all instances in the same LAN can get access to my swank server?
11:32:34
nij-
My main concern is that I want to let root to open a swank server, without letting the other users (on the same machine) to get access to it.
11:34:05
akater[m]
What should `(truename #P"")` return? I can't even infer it must share attributes with `*default-pathname-defaults*`.
11:38:43
jmercouris
I wrote a piece of code that I'm not very happy with: http://dpaste.com/DPG7WHVEN
11:44:46
shka
well, because then you would simply CL:FIND-IF the right cluster, and you could vector-push-extend to it if found
11:49:42
yitzi
If you need to do that kind of thing and position, find, member, etc don't work I would suggest writting a function to do it versus making an embedded loop. I personally find them to be confusing sometimes.
12:17:32
pjb
mrcom: perhaps because of an upgrade of the system? Since Apple collects crash reports, it may correct its system before the application developper can get around them ;-)
13:22:39
Guest87
I'm trying to generate a table from a list of lists representing the rows. The straightforward dolist works for text data. I need the first column to be buttons. I can't get a (:button) from a list to evaluate. I'm stumped.
13:26:22
rain3
show a working snippet with the straightforward dolist which works, maybe we can change it into something better
13:31:50
Guest87
(spinneret:with-html (dolist (row '(("a" "b") ("c" "d"))) (:tr (dolist (col row) (:td col)))))
13:35:51
Guest87
That produces two rows of two cells. My intuition was to substitute something like (:button "Test1") and (:button "Test2") for "a" and "c", or something similar.
13:44:30
rain3
I remember that spinneret in public interface only has macros , that's the reason it is awkward when we need to pass data to it other than hardcoded sourcecode and we must use eval
13:53:02
rain3
an alternative is to use this library instead https://gigamonkeys.com/book/practical-an-html-generation-library-the-interpreter.html https://gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html
13:53:27
eric
Thanks! Even if it's not perfect, I think it'll work. Yeah, I'm working though that book now.
13:56:20
tfb
dumb question: is there a version of quickload which loads only if not already loaded (like require ish)
13:58:30
tfb
oh. Does that mean quickload tells you what it *would* do? So it's 'To load ...' message doesn't mean it is loading it?
14:01:13
eric
Josh_2: close, and was another approach, but that hardcodes the column as a button. I was looking for a generic (make-table) that I could feed lists with tags in the list instead of the generator.
14:05:16
eric
I'd have a button in a cell when the data list had a (:button) in it instead of a "plain text" element. So it could be '((:button "button1") "b") or '("b" (:button "button1:)), with the items switching places.
14:18:30
eric
Interesting approach. I thought about listp, but if I wanted to use an (:a "http://somewhere") or (:img "smile.png") I'd have to write more cases on (car a), (car b), for each tag type.
14:28:15
Josh_2
you would do something like (if (listp <item>) (destructuring-bind (tag ele &rest args) <item> (:tag :name tag ele)) (:th ele))
14:57:29
Bike
technically it might be required that there's an expander so *macroexpand-hook* works, but there's no standard way to retrieve it
14:58:22
phoe
(block nil (let ((*macroexpand-hook* (lambda (expander hook env) (declare (ignore hook env)) expander))) (macroexpand-1 'foo))i)
15:00:00
phoe
if the macroexpand hook has access to the expander function, then I have access to the expander function
15:00:28
phoe
except above I forgot to RETURN-FROM it, and miraculously this code still worked despite not being correct
15:31:30
fbiaaa
hi! I'm using company-mode in Emacs but get no completion suggestion while editing common lisp file. I'm using two company backends: company-files and company-capf. Should I add some other backend?
15:46:19
beach
Having said that, I find slime-company more irritating than helpful most of the time.
15:47:24
beach
And often I get suggestions that are completely wrong for the context, and no suggestions that would be appropriate.
15:50:37
beach
I guess it's a consequence of the fact that Emacs and SLIM have very limited "knowledge" about the meaning of the Common Lisp code.
15:50:50
akater[m]
Asking again, just in case: what should `(truename #P"")` return according to spec? SBCL and ECL both seem to use `*default-pathname-defaults*` here but I don't see why it should be taken into account.
15:54:22
phoe
akater[m]: I guess that the NIL pathname directory gets interpreted same as (:RELATIVE)
15:55:01
phoe
and getting the truename of a pathname that is relative to the current directory and has all other components empty is going to result in the current directory
15:57:52
akater[m]
phoe: Thank you. So, `(:relative)` directory component should always be converted to nil.
16:06:15
akater[m]
Well, it says “not used”. I read it as, `(:relative)` should not occur as the value.
16:13:53
phoe
I read this as, "(:RELATIVE) is not going to occur in any pathnames returned by the Lisp implementation because it will use NIL instead, but if you use (:RELATIVE), then it's harmless, Lisp will treat it same as NIL"
16:22:50
phoe
continuations require the ability to store away control stacks, whereas the condition system works on a single control stack.
16:23:20
phoe
when an unwind is performed, whether by the condition system or by some other means, the stack is destroyed
16:25:18
lisp123_
Yeah I was able to do it via PG's Continuation Macros (which I'm debugging now, not sure if I made a mistake somewhere), but was something that just popped in my mind because he was using the function RESTART, which means he did it before the condition system entered CL
16:26:06
pjb
akater[m]: that's because TRUENAME must do the same as OPEN, and OPEN must call MERGE-PATHNAMES on relative pathnames. "For information about opening relative pathnames, see Section 19.2.3 (Merging Pathnames)."
16:26:27
lotuseater
lisp123_: but the other way around could be possible ^^ Continuations, the mother of all monads :D
16:28:19
lotuseater
wish me luck, later I have the first phone call with the customer for the new project
16:28:59
lotuseater
hah lisp123_ we had the same thought. there are also this paper with Imperative/Declarative
16:29:34
pjb
(let ((lotuseaster '())) (append 'luck lotuseaster)) #| ERROR: The value luck is not of the expected type list. |# (let ((lotuseaster '())) (append lotuseaster 'luck)) #| --> luck |#
16:30:14
lotuseater
or (setf (person-lucky-p *lotuseater*) t) or an amount between 0 and 1 but bigger than 0
16:31:59
pjb
lisp123_: we can implement delimited continuations in CL easily enough. But full contiuations need a lot of machinery (basically a re-compilation of the CL code).
16:32:37
lisp123_
pjb: what does it mean by "delimited continuations"? Is that the same as PG's restriction that every continuation should be nested?
16:34:28
lotuseater
when I told someone it's kind of runtime GOTO he just heard "GOTO" and said "no that shouldn't be used"
16:35:10
beach
That's what Turbo thought about Pascal, so they removed the only exception mechanism that Pascal had.
16:37:34
Bike
you might also have to copy frames to the heap to implement them, since the delimited continuation still has indefinite extent, which you can see in "stream-yield" where the continuation is stored in a lazy list
16:40:25
Bike
i just mean i don't remember whether they're theoretically equivalent to some kind of delimited continuation or what
16:41:09
lisp123_
Based on what I saw, I say they are, but there might be some points I missed, I'm only looking at the two at a superficial level
16:41:35
lisp123_
"If an =bind, =values, =apply, or =funcall expression occurs in a seg- ment of code, it must be a tail call. Any code to be evaluated after an =bind should be put in its body."
16:42:33
Bike
okay, but as i mentioned, that's not actually an accurate description of delimited continuations
16:42:45
Bike
that's just a continuation with dynamic extent, which we already have with block/return-from
16:46:19
Bike
block/return-from are undelimited continuations, i guess, since they abort control, unlike a delimited continuation
16:47:01
lisp123_
Yup and with material consequences for not being exact, given their use in estoeric code
17:00:56
phoe
you would still need to be able to encode the rest of the computation in some way, which still requires a CPS transform
17:04:24
Bike
restarts are just a dynamic namespace for functions. don't actually do any control transfer stuff themselves. i forgot.
17:05:35
phoe
it's easy to define a non-DX restart equivalent, everything control-flow-related is still up to THROW and RETURN-FROM and GO though
17:21:13
pjb
Bike: the argument is that they are not because: (let ((c (block cont (lambda (x) (return-from cont x))))) (list (funcall c 42) (funcall c 33))) does not work.
17:39:22
Bike
pjb: they are not what? undelimited? "undelimited" does not mean "indefinite extent". i know blocks don't have indefinite extent and i said as much