freenode/#lisp - IRC Chatlog
Search
22:33:24
fiddlerwoaroof
It's a quick way of generating functions like point-x point-y when you're using vectors to represent data.
22:35:46
aeth
fiddlerwoaroof: I'd much rather generate them separately because in practice you don't want 2D, you want 2D, 3D, and 4D when talking about points
22:36:23
aeth
Well, a general purpose graphical program will wind up working with all 3 because of how the various APIs work.
22:36:26
fiddlerwoaroof
I'm generally not dealing with these sort of things in a context where it makes sense for me to go fully generally
22:37:14
fiddlerwoaroof
:type vector is a useful way to get better ways of accessing vectors than just (elt some-vector 4)
22:37:49
aeth
It's not as useful as it could be because it doesn't give you the type definition, which a regular defstruct gives you.
22:38:09
aeth
I use define-array-and-type instead: https://gitlab.com/zombie-raptor/zombie-raptor/blob/48a75d6b543950c3581e5f413be8bd5c4cf3a357/util/array.lisp#L58-71
22:39:21
fiddlerwoaroof
I don't write game engines, so the performance doesn't matter too much to me
22:40:24
aeth
A vector gives you a lot of options, e.g. I often find that it's most convenient to split them into multiple values.
22:41:02
fiddlerwoaroof
Anyways, my use case is mostly things like dealing with CSV of a predefined format
22:41:18
aeth
If you write your own representation, you basically force someone to handle it as a unique case with with-accessors even if it's not unique.
22:41:51
aeth
(which often involves just translating it into a vector, doubling memory usage and slowing everything down)
22:42:09
fiddlerwoaroof
See, the way I would handle that would be to define a protocol of generic functions that are specialized on both arrays and my classes
22:42:33
fiddlerwoaroof
And, if the user had other things thy wanted to use, they could define methods as necessary
22:43:07
aeth
You can't define a method that specializes on arrays of a certain length because that's something that's only in the type, not in the class.
22:44:52
aeth
Well, ctypecase/etypecase is how you do that sort of thing, but it will only work for functions/methods of one, or maybe two, arguments before it quickly becomes impractical.
22:44:54
fiddlerwoaroof
Anyways, I suspect that the subset of CL I use and care about is fairly different than yours :)
22:49:28
aeth
fiddlerwoaroof: Immutable vectors would actually be a good way to handle both use cases, assuming the compiler was smart enough to reuse the old "immutable" vector instead of copying where necessary (which would be very tricky, actually, because the compilers mostly work on functions as a unit). Then the vector could be generic and specific.
22:50:17
aeth
i.e. then you could just say (immutable-vector 1f0 2f0 3f0) and the implementation would make it a single-float vector since you can't store some other type in there.
22:50:30
aeth
If you say (vector 1f0 2f0 3f0) it has to be a T vector because you could do whatever you want to it afterward
22:53:39
slaterr
is there an immutable vector in standard CL or some popular third party library? and immutable collections in general
22:54:25
aeth
You'd probably want it to be done at the implementation level and handled with a portability library, like threads, if you wanted efficiency.
22:55:10
fiddlerwoaroof
Anyways, you could totally have (vector 2f0 3f0 4f0) return a specialized vector as long as you have a check on assignment
22:55:13
aeth
pjb: Incorrect. #(a b c) is a literal vector, where mutation is undefined and should not happen. However, it is not tagged as immutable, at least in SBCL, so once you cross the compilation-unit boundary it will be mutated, with undefined and undesirable results (i.e. if you set b to d, then it will be saved as d next time you start the program)
22:59:13
aeth
You can, however, safely treat #(a b c) and '(a b c) as immutable within a function, and should do so if that's what you want and it doesn't cross the function boundary. (compilation-unit/file is a bit trickier, but it could be safe there as well)
23:04:57
aeth
Tagging literals as immutable would be a nice implementation specific extension that could eventually solve the issue, though, afaik. It wouldn't look pretty but you *can* create them in functions, e.g. `#(a b ,c)
23:21:14
jcowan
I wouldn't count on the output of backquotes being immutable: they are code, not literals.
23:21:38
jcowan
(that is "count on" even in the sense that you might count on it in a Lisp system that makes literals immutable.)
23:40:32
Bike
well, it's immutable in that it's undefind to modify it. i guess a system could expand it into (IMMUTABLE-VECTOR 'a 'b c) or something so it's tagged even though it's constructed at runtime.
23:43:17
jcowan
Or adopt the Racket solution whereby default conses *are* immutable, and you have to ask for mutability explicitly. This was done fairly recently, and remarkably few programs had to be changed.
23:48:26
jcowan
http://blog.racket-lang.org/2007/11/getting-rid-of-set-car-and-set-cdr.html lists only four basic cases where people used the mutability of conses in practice: for alleged efficiency with nconc and nreverse, queues (easily replaced with explicit mutable pairs), alist updating (easily changed to a functional solution), and the use of conses as a handy 2-element struct.
23:49:13
jcowan
Of course from a standards perspective it can't be done, no matter how nice it would be. Racket's implementations of standard varities have mutable pairs.
0:29:35
pfdietz
If you wanted to create an immutable vector, then (eval v), or perhaps (eval (list 'quote v)), would do it. Perhaps one of the few good uses of eval.
0:31:17
Bike
i think if there were actual runtime-immutable structures it would probably be better to expose a function to make em
0:59:02
aeth
pfdietz: You don't need to eval, though. You can also write a macro to produce essentially the same result, which would be even more preferable.
1:00:56
aeth
Bike: You'd also want to expose the subtype because you'd need type declarations to actually allow the compiler to assume that they're immutable when you use something like car or aref. (Well, you could also just directly declare them, but that solution is messier than a type one.)
2:15:42
fiddlerwoaroof
jcowan: hmm, isn't there a fifth case where you want to append an element to a list in O(1) time?
2:17:44
fiddlerwoaroof
Sure, but the advantage of using mutable conses is you don't need a conversion to use the underlying list with the rest of CL
2:18:00
fiddlerwoaroof
you just need to make sure you update the tconc function before trying to append again
2:18:46
fiddlerwoaroof
I dunno, I appreciate the value of immutability (it makes certain things much more reliable) but I do think we don't think about the costs
2:21:09
pfdietz
aeth: how does a macro do it? I'm thinking of the case where the vector is not known at compile time.
2:33:24
jcowan
fiddlerwoaroof: No, I mean a structure just to hold the first-pair and last-pair pointers; the list itself remains just a list.
2:35:42
aeth
pfdietz: The general case, which does require everything to be known, seems to be (defmacro literal (thing) `',(eval thing))
2:37:55
pfdietz
What I was getting at was that as soon as something shows up as a literal in evaluated code, it becomes unconforming for a program to modify it. So an implementation could flag it as immutable, even if it had been created at run time, not compile time.
2:40:02
pfdietz
Another interesting game: a way to make compile time constants behave as if they were created with hash consing (so equal constant are eql).
2:47:40
jcowan
Knuth, author of "Structured programming with goto statements" (a great paper) has outlived both of them.
2:50:17
jcowan
It's freely downloadable from https://epdf.tips/structured-programming-with-goto-statements.html
2:57:39
pfdietz
Instead, when you do (equal x y), if this is true and x and y are not eq, then do (setf (car x) (car y) (cdr x) (cdr y)) (say). Each comparison increases sharing.
3:01:33
jcowan
Goto's paper is from 1974 and is called "Monocopy and associative algorithms in extended Lisp". Tokyo: University of Tokyo Technical Report TR 74-03. It might be possible for someone to retrieve it given that.
3:06:08
pfdietz
https://www.cs.utexas.edu/~hunt/research/hash-cons/hash-cons-papers/monocopy-goto.pdf
5:38:24
p_l
beach: I think I recall reading about the idea in the past. Not sure if it wasn't mentioned in Peopleware
5:40:54
beach
The basic idea from Kahneman's book is that the brain has two modules, one fast and one slow. The fast one is lousy when it comes to statistics and arithmetic, and the slow one is lazy in that it tends to believe the fast one.
5:42:41
p_l
beach: it curiously connects with the AI saying of "hard things are easy, easy things are hard"
5:43:44
beach
It is not terribly thick. It is easy to understand, and it gets you thinking about our activity and how people around us think.
5:57:35
elderK
shka__: After looking into the MOP, I'm thinking of still using defstruct (or defclass) and suitable macros.
5:58:33
elderK
shka__: Although, I'm still kind of undecided. A real issue would be having defstruct-style inheritance restrictions.
5:58:33
p_l
Meanwhile I'm enjoying my just desserts for laughing at a friend whose baggage was waylaid by airline
5:59:02
elderK
shka__: I might even side-step the entire issue and force people to do "structural inheritance" themselves via composition.
6:02:27
p_l
It seems that everyone who took that transfer was affected, since me and my two coworkers all are in the same predicament
8:14:12
beach
A few minutes ago, I started an update of the Trisquel Linux system on my laptop. I am amazed to see a large number of errors and warnings. I think the situation is similar with established Linux distributions like Ubuntu.
8:14:13
beach
It looks like, in addition to aiming for a complete Lisp operating system, we should work on writing applications and GUI stuff like a desktop for GNU/Linux in Common Lisp. It could be done very nicely now that McCLIM is quite good (but not perfect of course).
8:14:52
beach
End-user application can be written so that they work both on traditional operating systems and on future Lisp operating systems.
8:21:11
dim
my current thinking about it is more related to people and “works for me” classics, either attitude, or diversity of hardware for Linux kernels, or setups or apps, etc
8:23:51
elderK
if destructuring-bind fails, because of bad input, should I just let that error propogate from my macro? Or should I translate it into something more meaningful?
8:24:10
elderK
Like instead of just, SOMETHING ERROR: Destructuring BAD!, I could say something like, Oh, hey, this is invalid slot form.
8:24:21
shrdlu68
elderK: "If the result of evaluating the expression does not match the destructuring pattern, an error of type error should be signaled."
8:25:12
elderK
shrdlu68: Right. The question is whether I let that "low-level" error propogate. Or whether I translate it.
8:25:23
elderK
I'm not sure what the usual... like, rules are, for macros that do a lot of destructuring.
8:25:54
elderK
Like, not just the things passed to the macro as arguments. I mean like, subforms that we process.
8:25:58
dim
beach: I have a hard time thinking that the programming language has such an influence on the quality of the programs, for me it's just that most developers think their job is to write code rather than maintain a solution/service to other users
8:27:53
dim
I've seen that a lot when consulting, one of my favorite example is about a web service that was broken because authentication cache was lost, and then the dev team was like “I think I know how to fix it, requires a couple days, plus tests”, and not one of those guys though about how to make it so that users could log in again *now*
8:28:43
dim
I think it's a good example because it shows clearly the lack of thinking about the users, in an obvious way with a web service currently broken
8:28:52
beach
dim: So I have a question for you. If you don't think the programming language has any influence on the quality of the code, why are you using Common Lisp rather than some more widely used language?
8:29:43
dim
beach: oh I think the programming language has lots of influence, yeah, just not the influence required to improve how developers think of their activity
8:30:26
dim
it's possible (and easy) to write crappy code in any language, I like CL better myself ;-)
8:34:01
beach
dim: My goal was not to change how developers think, only to make it easier to fix problems and to write software with better architecture and better safety.
8:35:57
dim
yeah I agree that CL offers better tooling than most other languages (hence my choice), the software still needs to be written by people who understand and cares about the quality in terms of end-user experience
8:37:02
jackdaniel
programming langugage may provide systematical ways to avoid certain classess of problems (and make fixing some other easier)
8:38:02
jackdaniel
I also tend to think though that problems which are inherent to some programming languages do not explot whole "crappy software" problem space :)
8:39:57
no-defun-allowed
#.(cons '+ (loop for x below 10 collect x)) => (+ 0 .. 9) though that's a bad example
8:42:28
no-defun-allowed
well it'd be a macro which takes a expression-making expression in and puts it out, something like (defmacro inline-macro (expander) `(symbol-macrolet ((whatever ,expander)) whatever))
8:54:29
_death
no-defun-allowed: usually such an operator is called META.. some years ago there was discussion here about a related one which I called METALIST :)
9:04:35
elderK
ebrasca: I'm still working on a binary types system. It might be worth discussing it in #mezzano, to help hash out what is truly necessary
9:09:16
shrdlu68
I think languages which insist on using indirections as a matter of course are easier to write crappy software in.
9:09:58
shrdlu68
Indirection as in "indirectness or lack of straightforwardness in action, speech, or progression."
9:10:59
elderK
shrdlu68: I'm still curious as to how I should handle errors wrt destructuring-bind. Like, do most libraries handle them in some way? Or do they just let the low-level thing propogate? Or perhaps they parse forms differently?
9:14:06
beach
elderK: Here are some useful hints with respect to handling exceptional situations: There are basically three kinds of exceptional situations: 1. Defects. 2. Resource exhaustion. 3. Others (part of a control structure). I think you are looking at 1. As long as they are detected and the place where they happen is signaled, you don't have to do anything in particular.
9:16:12
elderK
beach: I guess I'd just like to present a more useful error. Like, if the destructuring-bind error propogates up, like, it's an internal detail. People will be like, okay great, something doesn't work. And the context will be wherever it is. Where as, I would rather say, signal some custom condition that would say like, invalid whatever, etc. They'd know what they did wrong, with respect to using the macro.
9:16:28
beach
elderK: If a defect is signaled at the time the end-user is using the program, there is nothing that end-user can do to fix it. If it is detected during development, the programmer should be able to fix it without any particular assistance, as long as the place of the problem is indicated.
9:16:47
shrdlu68
elderK: I think having to handle an exception at destructuring-bind means some validation that should have been doen at some point before that wasn't.