libera/#commonlisp - IRC Chatlog
Search
6:03:06
hayley
I heard *eval-hook* was removed as it did nothing in compiled code, making it rather awkward.
8:31:49
pve
Hi, if I nreverse a vector with a fill pointer, will the result also have a fill pointer?
8:37:20
phoe
sbcl, ccl, ecl, abcl, clisp, lw, acl all pass (let ((v (make-array 5 :initial-contents '(1 2 3 4 5) :fill-pointer 3))) (assert (eq v (nreverse v))))
8:38:41
phoe
so, yes, all implementations mutate the vector in-place rather than constructing a new one
8:39:52
phoe
pve: if the returned vector is EQ to the original one, this means that it has a fill pointer, and by common practice you can depend on this
8:53:27
jackdaniel
truth to be told implementing reverse usually involves (nreverse (copy-sequence seq)) unless you are a masochist
9:19:17
phoe
Shinmera: nope, I am too lazy to do this, I just type the following in my repl: sbcl ccl ecl cmucl abcl clisp acl
9:19:52
Shinmera
phoe: you might want to do it though, it's quite convenient for exactly that https://github.com/shinmera/cl-all
9:20:48
phoe
Shinmera: yes, I am aware; I just can't do it at the moment since my will and strength are going elsewhere
11:11:48
pjb
pve: "whereas nreverse might modify and return the given sequence." "For nreverse, if sequence is a vector, the result is a vector that has the same actual array element type as sequence." "For nreverse, sequence might be destroyed and re-used to produce the result. The result might or might not be identical to sequence." " When sequence is a vector, nreverse is permitted to re-order the elements of sequence in order to produce the
11:13:09
pjb
pve: you can do: (let ((r (nreverse v))) (unless (eql r v) (replace v r))) to reverse the fill-pointed vector in-place.
11:15:20
pjb
shunter: a typical case, is (with-input-from-string (*standard-input* "foo") (read)) or (with-output-to-string (*standard-output*) (print 'hi))
11:15:59
pjb
shunter: the macro should let the user declare the variable special if wanted, but by default, it should be lexical binding.
12:38:43
_death
although NREVERSE entry hints at what it's permitted to do to a vector, I'm not sure it's ok to assume that you can pass it (after destruction) to REPLACE as a target, if NREVERSE did not return it.. in any case seems bad style
13:00:45
Nilby
I'm pretty sure one can make an extensible sequence in sbcl which would violate the assumption that nreverse returns the original.
13:33:02
_death
good, you took the bait :)... we can start with make-array's :initial-contents parameter... it can't take multidimensional arrays
13:35:22
_death
second, (coerce (make-array '(3 3) :element-type 'single-float :initial-element 1.0) '(simple-array t (3 3))) fails though the single dimension case is ok
13:35:23
Nilby
:initial-contents is perplexing. I feel like what's the point if you have to make it be a list?
13:37:21
_death
third, there's no standard readable printed representation for specialized arrays (other than strings and bit-vectors).. so if you print them readably, an implementation can signal an error or use nonportable syntax (like sbcl).. so if you wish to print some piece of code readably, you need to be aware of this pitfall and act accordingly
13:39:15
Nilby
I agree coerce could be a lot more coercive in many cases. One might wish it was generic.
13:41:41
Nilby
I've too gotten bitten array (non-)readability. I sometimes feel like arrays should have more subclasses and the simple ones should always work, for things like coercion and readability.
13:44:43
Nilby
displaced arrays are sometimes troubling, but I still like them. I feel like for things that could prove it okay, a displaced-subseq could make a lot of things quicker.
13:45:45
_death
in code that cares about performance, though, I often need simple arrays and displaced arrays become much less useful
13:46:31
emacs-dwim
_death: sbcl's printed arrays are portable readable though, just not portably printable?
13:47:35
phoe
emacs-dwim: (let ((v (make-array 5 :initial-contents '(1 2 3 4 5) :fill-pointer 3)) (*print-readably* t)) (prin1-to-string v)) ;=> "#(1 2 3)"
13:47:51
_death
emacs-dwim: no.. it looks like #A((3) SINGLE-FLOAT 1.0 1.0 1.0) which is not standard syntax
13:52:07
jackdaniel
haa, this is funny, ecl has similar syntax, but first two arguments are reversed
13:56:16
Nilby
just the basic serialization problem. if you print values and try to re-read them, in a different impl, but of course even a different image
13:57:56
jackdaniel
ah, I see - so its about reader/writer; I thought that something repl specific and I couldn't think what (admittedly repl is haf about read and print)
14:00:08
jackdaniel
#< enables a secret language that common lisp doesn't understand - it's just in case when it revolts
14:02:16
Nilby
I feel like a lot of these problems could potentially be solved by more CLOSification of the built-in things
14:03:20
jackdaniel
you may have hash-table as a standard class, but how do you serialize it? it is not that hash table maintains an assoc list
14:21:26
phoe
you can always write a custom macro and have custom lambda lists in it, you don't really need a library for that
14:22:02
phoe
as for existing lambda lists defined by the specification, there's no way to extend them and you'll have to modify your implementation in order to support them
14:22:29
jackdaniel
(defmapckage better-cl (:use)) (in-package better-cl) (cl:defmacro defun (name args cl:&body body) go!))
14:24:41
emacs-dwim
let+ combines several binding forms, multiple-values. It's user-extensible. So I added ppcre & trivia to it for example. I want to write defmacros that &match trivia patterns and bind them.
14:25:41
beach
emacs-dwim: The current idea with some of us is that the s-expression-syntax library provides parsers for various standard expressions. And it should be possible to define custom parsers for extended lambda lists.
14:26:23
phoe
as for the lambda list in DEFMACRO, there is no portable way to extend its lambda list other than supplying your own variant of DEFMACRO that can do this.
14:26:39
beach
emacs-dwim: It is tricky stuff because custom lambda-list keywords must also come with a description that says where they can appear, if and how many arguments they take, if they can appear several times, etc.
14:34:06
beach
emacs-dwim: It is not quite ready for widespread use, so you might run into some issues. But it would be good to start experimenting with it.
15:22:57
beach
nij-: Of course, you are somewhat out of luck, because BOUNDP doesn't really tell you what you want. There is some annoyingly ambiguous language in the standard. Sometimes "bound" means "has a value", and sometimes it means "has a binding that may have no value".
15:24:22
beach
Like if you do (DEFVAR XYZ) and then (BOUNDP 'XYZ) you get NIL. Yet, XYZ is a variable.
15:25:43
jmes
Is there a way to shadow a binding with a symbol-macro whose expansion references the original binding? e.g. this is what I want to do, but it exhausts the control stack: (let ((a 1)) (symbol-macrolet ((a (1+ a))) ...))
15:26:07
White_Flame
a really silly way is to do packagename:<tab> and see everything that is earmuffed with asterisks :-P
15:27:31
Shinmera
(definitions:find-definitions *package* :type 'definitions:special-variable) will give you whatever variables are accessible in the current package.
15:28:10
beach
jmes: How about something like (let ((a 1)) (symbol-macrolet ((mumble a)) (symbol-macrolet ((a (1+ mumble))))))
15:32:55
Bike
symbol macros just expand in the same context, so if the original variable appears in the expansion it will just be expanded again
15:36:06
jmes
Bike: yeah, so what I've learned is if a symbol-macro expansion has its own symbol inside it then the stack goes boom, sadly.
15:56:00
Bike
of course, for something like 1+ there's no need to refer to the actual binding, so (let ((mumble a)) (symbol-macrolet ((a (1+ mumble))) ...)) would work, but maybe you want it as an actual place
17:30:06
pjb
jmes: (let ((a 1)) (flet ((get-a () a)) (symbol-macrolet ((a (1+ (get-a)))) a))) #| --> 2 |#