freenode/#lisp - IRC Chatlog
Search
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
21:37:54
alandipert
one question i had was, is there an easy way to initialize a struct from a list of slot values?
21:39:24
alandipert
i didn't care to look but i imagine there's a way to get the list of matched groups from cl-pcre, and so i thought yeah - that function would be tigher if i applied that list to a constructor
21:40:16
Bike
if you do (defstruct (claim (:constructor make-claim (id x y width height))) ...) you should be able to call make-claim like (make-claim id x y width height)
21:45:02
Bike
i don't know if you can do that with ppcre, though, especially since you also need to parse stuff into integers.
21:45:03
tumdum
alandipert: your claim parsing is much nicer than mine: https://git.sr.ht/%7Ettt/aoc18/tree/master/day3.lisp ;)
21:50:25
_death
cool.. mine was made in a hurry and to the noise (music?) of a handyman hammering ceramics in my bathroom https://gist.github.com/death/fd93cf68c475a303c07a2ae5890439e9
21:56:00
eminhi
now this was noise. https://bpaste.net/show/dee55ad8acae . I only knew split-seq utility.
22:48:00
dim
tumdum: I'm trying to go CL only for now (until I'm bored), as an excuse to learn the standard better, https://github.com/dimitri/AdventOfCode/blob/master/2018/d03.lisp#L27
22:49:36
dim
_death: I used repeat instead of below in my loops so that I don't have to compute the end index ;-)
22:49:57
dim
(defun update-fabric-claims (fabric claim) (loop :for row :from (claim-top claim) :repeat (claim-height claim) :do (loop :for col :from (claim-left claim) :repeat (claim-width claim) :do (incf (gethash (cons row col) fabric 0)))))
22:51:57
no-defun-allowed
is there a case-lookalike that expands to a lookup table with O(1) access?
23:06:21
no-defun-allowed
my issue would be creating the table at compile time with the correct lexical scoping
23:39:37
aeth
e.g. (dotimes (i 4) (dotimes (j 5) (dotimes (k 6) (format t "~D~%" (+ i j k))))) vs. (loop :for i :from 0 :below 4 :do (loop :for j :from 0 :below 5 :do (loop :for k :from 0 :below 6 :do (format t "~D~%" (+ i j k)))))
23:41:38
aeth
And if you have a simple repeated iteration pattern in your code (probably 6 or so times for it to be worth it) that cannot be expressed concisely outside of loop but you can define either a do-foo macro or a higher order function using do/do*/dotimes/loop/map/mapcar/maphash/etc., you should do that imo rather than directly use loop in that case.
23:42:30
aeth
But if you're e.g. doing some numerical algorithm that involves stepping through 5+ different variables, using both :with and :for, with a lot of complex logic going on, then you probably should just use LOOP.
23:45:28
aeth
(You could also use DO or DO* for many of these complicated iterations, but then the first thing you'll hear from your peers is "I can't read this")
23:48:06
aeth
DO/DO* are great for macro targets, and they're basically just LET with a(n optional) step, a terminator, and a return value.
23:52:42
aeth
The three points of confusion are probably (1) the terminating condition is the opposite of what you might expect, (2) the terminating condition and the optional return value are in the same s-expression, and (3) a well-written DO often doesn't have a body at all.
23:54:45
aeth
With LOOP you can specify :until/:while, the return is pretty clearly marked, and the step (:for) vs. not-step (:while) forms are clearly distinguished instead of relying on an optional third element in a binding's list.
0:36:02
no-defun-allowed
depends on the context, i think DO would be better for looping, but it does expand to TAGBODY in the end
0:36:33
aeth
eminhi: In most implementations DO will macroexpand to block over let over tagbody and DO* will macroexpand to block over let* over tagbody, e.g. it's pretty straightforward in SBCL with this: (macroexpand-1 `(do ((x 42) (y 1 (1+ y))) ((> y x) (+ y x)) (format t "~D ~D~%" x y)))
0:37:12
aeth
(It actually has two TAGBODYs in SBCL's macroexpansion of DO because DO-FOO forms have an implicit TAGBODY so you can write your own labels/GOs in there for more complicated iterations.)
0:39:29
eminhi
I want to reason with something more abstract than TAGBODY. and I really dont want to target loop.
0:39:32
aeth
eminhi: If what you want is ultimately BLOCK over LET over TAGBODY over TAGBODY then DO (or DO* for LET*) can save a lot of lines in your macro
0:40:13
aeth
If you want something more complicated (e.g. MULTIPLE-VALUE-BIND) then you'd have to work with TAGBODY directly, or you'd have to work with someone else's more advanced macro.
0:56:44
PuercoPop
How would you phrase the relationship between the method and the specialized parameter? e.j. "The EMACS-INSPECT method that specializes in HASH-TABLE"?
0:58:28
PuercoPop
Also can someone with access to SLIME check if inspecting the resulting hash-table from the following expression breaks for them?
0:58:29
PuercoPop
(let ((ht (make-hash-table))) (setf (gethash #C(0 1) ht) t (gethash #C(0 2) ht) t) ht)
0:59:56
PuercoPop
Basically the problem is that it applies < to complex numbers, that only applies to reals
1:00:56
PuercoPop
I'm going to recommend to change the typep to real. However I'm wondering it would make sense to implement an ad-hoc order
1:03:12
aeth
PuercoPop: Distance from 0 (assuming it's on the real-imaginary plane) with the real part as a tie breaker could be another way to sort complex.