freenode/#lisp - IRC Chatlog
Search
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.
20:15:05
jmercouris
when I only want to use the second value that a function returns, is there a way to do that without using multiple-value-bind and (declare (ignore first-value)) ?
20:26:36
pfdietz
There should be a place whose effect is to discard the value assigned to it. (values), I guess but can that be used inside another (values ...)?
20:34:30
White_Flame
but yeah, the store would still occur, while the ideal would be to elide it altogether
20:36:58
White_Flame
yeah, have been trying that sort of thing as well. it seems to expand with a weird NIL injected
20:39:47
White_Flame
(setf (values (values)) 1) seems to be the shortest failure case I can construct
20:40:34
White_Flame
but (setf (values a (values)) (values 1 2)) shows the broken lambda parameters that get expanded
20:56:05
dim
ahah I just did my first implementation of anagrams-p using the prime number products trick, it's fun
21:35:45
alandipert
my day 3 AoC - thanks in advance for criticism. i consciously avoided loop and hash tables (until the end...) and flow was much improved https://github.com/alandipert/advent-of-code-2018/blob/master/day03.lisp