freenode/#lisp - IRC Chatlog
Search
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.
10:13:41
ogamita
dim: it's not the same job, writing/debugging programs, and helping users. In your specific case, helping the users to login back right now would probably involve completely different otols and solutions than correcting the program so the problem doesn't occur in the first place.
10:16:41
ogamita
I saw that early; it's a career choice to either cater to 1 user, or to develop and debug programs hopefully for millions of users. The former is closer to concierge work really… (not saying it pejoratively, I mean high-end high quality conciergery).
10:17:44
ogamita
And for programmers, the choice of programming language definitely implies differences in the mental load and the attitude of the programmer, leading to the presence or absence of whole classes of bugs.
10:18:13
ogamita
elderK: if you use emacs, there's automatic expansion of names from abbreviated inputs.
10:19:26
elderK
ogamita: I have no problem typing such a name. But like, iono, it feels very wrong :P
10:20:09
ogamita
it's a style. You can choose to use shorter names. The problem is to find meaningful short names.
10:21:24
ogamita
elderK: the problem of error handing is a general program, it's not specific to a form such as destructuring-bind. Since in lisp so many operators already perform run-time checks and signal errors, you can start by basically ignoring all error conditions, and letting lisp signal them. The advantage: simple, the inconvenient: error messages are not meaningful to the user.
10:22:15
ogamita
elderK: then you can add some validation and error checking at the interfaces. Assuming that the data is validated at the interfaces, you should be able to prove that no error will occur in the internal code. (ah!)
10:23:41
jackdaniel
that's another flip of the coin: common lisp makes a space for a class of bugs which are uncommon in statically typed languages (destructuring-bind is a very good example of that actually)
10:24:02
ogamita
elderK: and finally, you can develop a whole ontology of error conditions, including them in the API, (you can even have conditions that are not signaled in the current implementation,but that could be if the implementation changed!) and you could check or handle all condition very meticulously.
10:24:25
ogamita
in this later case, it is easy to have more LoC about error handling than actual code…
10:25:17
ogamita
jackdaniel: not more errors, rather fewer, but distributed differently on the lifecycle of the project.
10:25:48
jackdaniel
I'm not talking about quantity now but rather different kinds of issues which may occur in code
10:25:51
_death
elderK: in that case you could have a generic function SLOT-NAME with a method that specializes on INVALID-SLOT-DESCRIPTION
10:25:55
dim
ogamita: I totally disagree with you, code is not written in the abstract, the goal of writing code is not to have written code, it's there to serve users. If you can't be concerned about users of your code, please stop writing any code.
10:26:09
ogamita
The only difference is that since run-time checks must be performed ANYWAYS, because shit happens, lisp always include them so it can spare them at compilation time. Just add tests to detect them at "compilation-and-test" time, instead of at run-time.
10:26:49
jackdaniel
we are talking about practices which are encouraged by language design, not about technical possibilities
10:27:06
jackdaniel
if we had followed this trail we could make up a crappy argument, that c is as safe as cl, because you may write cl in c
10:27:29
ogamita
dim: I won't make a judgement, but I notice that developers catering to millions or billions are more wealthy.
10:28:18
ogamita
jackdaniel: definitely! So I guess now you compile all your C programs (eg. including ecl) with a whole gamut of -fsanitize options, right?
10:32:47
no-defun-allowed
Dare I say it, linking to your Usenet quote collection is also a bit lazy too.
10:33:12
ogamita
dim: I made very relevant points. You are confusing two situation. What you witnessed, was mismanagement, not a programmer problem. The managers made the mistake to hire a programmer when they should have hired an operator.
10:34:35
ogamita
In classic IT departments, there's a clear separation between programmers who work on time ranges over months or years, and operators who work on time ranges over hours.
10:35:32
no-defun-allowed
I think that's a bit silly, though I've only had one experience in a normalish development group.
10:35:43
ogamita
But even if you do agile and devops and reduce the difference in time scale between the two categories, it still exists. You just witnessed that.
10:35:53
dim
ogamita: it's funny that you understand the situation that way, because my point is exactly that the developer should be concerned with fixing the service/application for its users, full stop. You're making the point that dev and ops should be separated. Well, we disagree.
10:35:56
jackdaniel
that sounds too much like "people as cogs in a machine" to me, I'll pass on "minding only what's required in job description"
10:37:03
jackdaniel
elderK: around 80 is good, but breaking a line just for a sake of breaking it doesn't make sense
10:37:07
no-defun-allowed
Then again, I was the only one who knew (relatively) how to deploy a Lisp program.
10:37:30
jackdaniel
80 lines gives you three columns with a reasonable font size vs 1080p resolution
10:37:40
no-defun-allowed
Usually between 80 to 100, I do cut some slack as Lisp usually has nice clear names.
10:38:12
ogamita
What seems reasonable to me is to keep indeed 80 columns, but discounting the indentation!
10:38:44
jackdaniel
being 80-line dogmatic may bite you (i.e you may start refactoring completely fine functions because some method name is too long)
10:38:56
elderK
ogamita: I imagine you don't care about like, the margin so much because you know, you can just reformat the sexps to whatever limit.
10:39:08
no-defun-allowed
If they do get that long, I consider it a lack of abstraction instead of long names or bad positioning of sexps
10:39:25
ogamita
And sometimes, it's easier to read long lines (eg. when you write codes in columns), than to fit it in 80 columns and break the 2D nature of your code.
10:39:35
elderK
jackdaniel: It's less dogma for me and more necessity. I can only fit so much horizontally on screen due to zoom.
10:39:58
ogamita
elderK: just because you can scroll laterally as easily as you can scroll vertically. So as long as complete lines are visible, it's ok.
10:40:12
no-defun-allowed
Some geometric or aesthetic heuristics like that usually help me write clean code, but I don't see it as a hard constraint.
10:40:37
elderK
ogamita: Scrolling horizontally is shit if you wind up spending most of your time moving left/right/left/right constantly.
10:41:22
elderK
And in general, you will want to see context around the line in particular you are reading.
10:41:44
no-defun-allowed
Another is if there's too many )'s at the end of an expression, I missed something, it's CL-WHO or too much stuff in one function.
10:41:56
elderK
In general, if I keep hitting the margin, it is an indicator for me that I may be doing too much in one place.
10:42:48
jackdaniel
they've once stole 10% of a very sophisticated military code from pentagon. it happened to be written in lisp. sadly all they got was ")))))))))…"
10:43:06
no-defun-allowed
(Rainbow delimiters in Emacs have a period of about 8, which is the end of my comfort zone.)
10:43:49
no-defun-allowed
That joke is so old, they had to update it when s expressions came around.
10:48:13
_death
anyway, the answer to indentation/too many closing parens and other issues is https://adeht.org/usenet-gems/one-function.txt
10:50:22
ogamita
elderK: what do you not like in m-expressions? https://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/m-expression/index.html
10:53:09
ogamita
_death: definitely. Again, it's always the same thing, functional abstractions (sicp etc).
10:54:07
ogamita
elderK: I do too. Anyways, M-expressions are just a prototype. It was planed to design a nice syntax for lisp, but since s-expressions caught up, that project never realized.
12:46:06
jcowan
dim: (on the broken authentication cache): Sounds like the cache was not a cache but the source of truth for authentication. A lost cache should only have slowed things down, no?
12:50:42
shka__
find closest code by name, split existing code into hierarchy, find neighboors, but list remains inmutable as a whole
12:52:18
beach
shka__: When you ask questions like that, you should talk about operations first. A list of the codes (as you initially said) would be of no use.
12:53:55
beach
You said that you wanted to represent a list of code. A list of codes is (A00 A01 A02...). Such a list has absolutely no use.
12:53:59
Odin-
"X35 Victim of volcanic eruption" ← That's a short code for what can't be too common.
12:54:32
beach
shka__: So you did not mean that you wanted a list of codes. You meant something else, and that something else is a description of an abstract data type, which is defined by its operations.
12:55:48
elderK
Aye. How you operate on the data kind of leads to what kind of data structure (or structures) you populate / manipulate.
12:55:49
Odin-
With a structured code system, most of the desired operations _should_ be doable using string manipulations, so there wouldn't be a need to store a complete list of codes.
12:57:05
shka__
find closest code by name, split existing code into hierarchy, find neighboors of code (by tree hierarchy)
12:58:07
elderK
It does look like you could do hierarchical lookup just using string manipulation. A prefix tree of some sort, Patricia maybe, might be helpful: https://en.wikipedia.org/wiki/ICD-10_Chapter_I:_Certain_infectious_and_parasitic_diseases#(A00%E2%80%93A09)_Intestinal_infectious_diseases
12:58:22
jackdaniel
I don't understand this discussion. You've asked "what data structure", "for a LIST"(!), "which is TREE"(!)
12:59:05
elderK
shka__: But really, you could just... separate it into components easily enough. And build a trie.
12:59:18
shka__
jackdaniel: i am not asking about data structures, i just want to know if loading it during load operation is a good idea
12:59:19
Odin-
If you're looking up "by name" then you're presumably also working with the descriptions given, so you'd also have an index in the other direction.
13:07:24
_death
shka: you can store it in a csv, which is easy to update.. you can provide a function to read it and build the database, and let the user decide when to do that
13:08:30
shka__
_death: wouldn't it be more convinient if it would be loaded up when system is loaded automaticly?
13:24:27
ogamita
shka__: first it should probably be data. Now the criteria are the volume and the mutability. On one hand, it's relatively sizeable data, you might want to keep on file and load only on a as-needed basis. On the other hand, 14000 items in gigabyte memories is nothing, so it could also be loaded in whole. On the other hand, while it is mutable (it can be updated from time-to-time), we can assume that while the program is running the
13:24:27
ogamita
data won't change, so basically immutable. In consequences, choosing to define it in a toplevel form, at compilation-time, and loading it as literal data by loading a fasl file is an option.
13:25:19
ogamita
shka__: I don't particularly like this option, I'd rather save the data in a file, and read this file when initializing the application, but given the constraints I listed, saving it in a fasl and loading it as literal data is a quick and easy way to do it.
13:26:02
ogamita
shka__: notice that the source of the data base may be a cvs or a PDF from "upstream", and you can process this source at compilation-time!
13:26:36
dim
note that we still don't know what's the use of the data… the generic “lookup” answer isn't very satisfying
13:27:45
ogamita
One advantage of puting it in a toplevel form and a fasl file, is that if you save an excutable image, the data will be there without having anything to do. On the other hand, if you keep it in a separate data file, once the excutable image saved, you will still have to install the data file along with the executable on the user file system and to load it at run-time.
13:28:13
ogamita
dim: imagine it's a big table of error code -> error message code. It basically behave the same.
13:29:41
jackdaniel
nb: this doesn't play nice if you build the executable (and not dump the image), (defparameter *foo* (load-from-my-file)) if that file is not present at the host system will fail
13:29:43
dim
ogamita: I don't know that. I know how error codes in SQL standard and PostgreSQL works, and that's completely static, basically you have a condition class with a sqlcode slot you pick the slot in the code statically depending on the situation
13:30:22
dim
if that's the same thing with this ICD10 then it's easy, just add a icd10 field to your medical-condition condition definition
13:31:26
jackdaniel
dim: you need if you do not save the image. toplevel forms are replayed upon start in that case
13:33:03
jackdaniel
also I can imagine a build system which calls compile-file to have fasls (without loading sources first)
13:33:58
ogamita
dim: error messages are not completely static. They change from one version to another. So you need to update that kind of metadata from time to time.
13:35:25
ogamita
dim: you need #. to save the data in the fasl file and the lisp image (so it works on both implementations with lisp images, and implementations with elf executables).
13:35:55
dim
what I mean is that I don't suppose that the medical application is going to pick the error code depending on machine generated diagnosis, I would suppose it's an input system for a human medic, but we don't know that yet
13:38:32
ogamita
So you will want to update it and generate a new version of the application every year. Which is good, since then you can make pay customers every year :-)
14:13:53
ogamita
shka__: the other option, is to download the data from the web. This means the customer needs an internet connection, so you can check the validity of his license ;-)
14:17:13
ogamita
For internal tools, it's ok. You use it internally, you have the sources, in case of problems you can correct easily.