freenode/#lisp - IRC Chatlog
Search
11:59:23
lukego
yeah nah in my own application code I prefer to limit the number of variables, e.g. platforms and compilers, to as narrow as possible. I'm not writing libraries for other people here.
12:00:24
lukego
and I suppose that I _am_ writing common lisp code if I specify the detailed types of my key functions using Common Lisp type declarations, it's not my fault if some compilers choose to ignore that :)
12:01:01
jackdaniel
declare is described in the standard as a "promise to the compiler", not a safety measure
12:03:28
lukego
ok that's on me then. but that's always been my development philosophy. cheat as much as possible to get the program to the point where it is worth porting, rather than get distracted with portability and risk that the program doesn't get finished at all
12:04:14
lukego
easier to port a working non-portable program than to finish an incomplete portable program.
12:05:46
jackdaniel
I'm not convinced that this is a proper justification of sloppy declarations, but it is your program so there is no need for me to be convinced ,)
12:10:22
lukego
Just seems like it will lead to more clutter to me. I'm already putting effort into untangling my test cases from my application logic so that I can look at each one in peace from the other
12:11:26
lukego
(make-foo :x 1 :y 1) verses (let ((foo (make-foo :x 1 :y 1) (check-type foo (satisfies valid-foo?)) foo)
12:12:49
lukego
I guess that's hard to answer since it depends on how initialization is done and how much depends on the context of the callre
12:14:21
lukego
Maybe. There's also e.g. the quid-pro-quo library that provides another valid solution, which has a nice separation-of-concerns feel about it to me, but that's not in quicklisp and frankly has quite a bit of machinery in its implementation.
12:15:03
lukego
there are also around methods and before methods and after methods... so don't tell me there isn't more than one way to do it thankyouverymuch :)
12:20:03
estest
Making use of SBCL's behavior of type checking declares is a nice bonus of developing in SBCL, much like its generally fast assembly output (especially when you declare types) is a nice bonus, though if your program actually should rely on types being checked, an explicit check-type or some other mechanism is a good idea.
12:22:25
lukego
quid-pro-quo seems to be not in quicklisp, and to have dependencies that are also not in quicklisp, which is a bit of a enthusiasm damper
12:27:13
pyc
Need feedback with code style: https://plaster.tymoon.eu/view/2316 I have auto-fill-mode enabled, so as I type long strings, Emacs automatically inserts line-breaks. Is this good code formatting? I am curious about the two spaces that Emacs has inserted as prefix after each line-break.
12:27:26
lukego
and trying to load it is giving me a "This is probably a bug in SBCL itself" error involving metaclass compilation, which sure does play into my "gee that looks like a lot of implementation machinery" first impression
12:27:36
estest
I also find leaning on the implementation against portability to only be worth it when you need a particular feature it has for which there's not a good portability layer. Like why use sb-thread:make-thread when bordeaux-threads exists. Otherwise being portable and even testing in other implementations from time to time doesn't really slow me down, and can sometimes find tricky bugs earlier.
12:28:32
lukego
Just now I'm only trying to find a sufficiently pleasant way to write testing code such that I will actually do it. The main barrier to instrumenting my code with tests is clutter and verbosity.
12:31:31
lukego
Maybe a good CL lawyer can help me find an acceptable formulation of the serapeum:-> function type declaration macro, such that function type declarations are strictly for documentation purposes, and any utility in the form of test coverage on SBCL is purely accidental
12:33:50
lukego
(and in truth I'd expect the really proper test coverage to come from approaches like beach outlined, with high-level functional testing, and what I'm trying to supplement that with now is just some scaffolding to help me get the nuts and bolts right before the structure is in place)
12:35:09
heisig
lukego: For my last project, I defined my own document-[function,variable,...] macros that expand into (setf (documentation ...) ...) and some fancy extras.
12:35:13
shka_
secondly: it allows implementation to use the inferred types to warn when you are using aref on list ans so one
12:35:53
shka_
however, you should not count on these to give you runtime errors when types mismatch
12:35:55
heisig
One such extra was that it would take a list of forms and add them (and the results of evaluating them) as examples to the documentation string.
12:36:09
estest
pyc: I'd prefer the spacing to align the text with the first character of the string, i.e. the A in "Alice is.." is on the same column as the b in "been working".
12:36:35
estest
But I'd only do that for docstrings or strings I know will be processed for display and have the newlines/lead spacing taken care of; for a raw record your example suggests you probably don't want newlines in the source string, so consider letting it be long (and word-wrapping) or concatenating broken up bits...
12:37:40
shka_
lukego: so in summary, ftype declarations are useful in a certain context, but not beyond it
12:38:45
lukego
shka_: that sounds reasonable. but if I'm honest I'm thinking of them as assertions that can be allowed to propagate (and inhibited from doing so in performance sensitive contexts)
12:38:59
shka_
my personal rule of thumb is to use ftype declarations for internal functions, but not for the interface functions
12:39:04
lukego
I'll see how I go, probably they are not actually the right tool for the job, but ask me again in ten minutes..
12:40:34
shka_
use check-type for stuff that is expected to be called by the user, you may use ftype and declare for the internal stuff (though, at least initially check-type is not a bad idea either)
12:41:40
shka_
besides, sbcl can deduce returned function type even without the explicit declarations
12:42:38
lukego
yeah but there are types and then there are types e.g. I might want to provide a (satisfies foo) type that's stricter than what sbcl would infer.
12:43:38
lukego
but maybe it's time for me to "read the room" and see that SBCL-specific hacks are not popular topics for discussion in here even in the early freewheeling days of a project that are always spent trying out and discarding bad ideas anyway
12:44:35
shka_
lukego: well, in that case you may define returned type of the function, but check-type the input types
12:45:18
shka_
overall, simply don't think about type declaration as suitable for checking the input types
12:45:26
lukego
I'm much more attracted to out-of-band top-level declarations like (-> read-floorplan (string function) valid-floorplan)) than anything that adds multiple lines to the actual function definitions
12:45:39
lukego
but maybe that will pass, I have been too busy fighting with you guys to actually try it yet :)
12:46:21
lukego
that's an extreme position since I'm using SBCL and SBCL says that it treats types as assertions and guarantees that they will be tested under specific conditions that I can ensure
12:46:22
shka_
well, as i said, it is FINE for internal functions that are not exposed, it is NOT FINE for external functions
12:53:02
splittist
Having just reviewed a project of mine with function names like FROB and PROCESS I will refrain from giving further programming advice (:
12:54:36
lukego
One happy thought is that with any kind of test instrumentation in my application code - whether with CHECK-TYPE, or FTYPE, or QUID-PRO-QUO - I can probably throw away these boring unit tests that I've been writing. The main purpose of those is just to keep silly errors from propagating e.g. a function returning the wrong object and finding out later when it's hard to track down what happened.
12:55:51
lukego
The situation I want to avoid is "oh, whoops, that innocent refactoring I did in PREINIT-FROB forgot to set the FIZZ slot, and that's why I have these twenty *sldb* buffers popping up all over the place
12:56:26
lukego
I should have known that if I found myself writing unit tests I was probably doing something wrong...
13:35:33
pyc
marcoxa: do you know why Emacs decides to insert two spaces to indent all the continuation lines of my long string in the example I shared earlier: https://plaster.tymoon.eu/view/2316#2316
13:36:59
beach
pyc: Emacs is not great when it comes to indenting Common Lisp code, but it's the best we have.
13:38:15
andreyorst
beach: I've thought that Emacs when used with SLIME or SLY gets some info from runtime to indent code more or less correctly?
13:38:56
beach
andreyorst: Yes, but it is fundamentally broken, because of the way it decides what is code and what isn't.
13:40:29
beach
andreyorst: Try the following experiment: In a buffer in Lisp mode type (let ((aaaaaaa<RETURN> and observe the indentation of the next line
13:41:41
beach
So it has not analyzed the text enough to know that we are dealing with a LET binding.
13:43:46
andreyorst
with let I don't see any problems, it aligns the indentation to last opened parenthesis
13:43:58
Nilby
The depth of my disgruntlement with Emacs is nearly unfathomable. But it's STILL the least sub-optimal.
13:45:12
andreyorst
yes, I understand, I just thought that it does a bit more analysis, and will think that prog1 is a binding, not a call, that's what kinda weird
13:49:46
Nilby
I've recently been trying out the "pretty printer" to format code, but as you may know, without some undiscovered tweaking, it mangles it.
13:53:51
Nilby
One of my faviorite semi-ironic quote from the spec is: "the necessary flexibility is provided for individual programs to achieve an arbitrary degree of aesthetic control."
13:59:59
Xach
Nilby: the pretty-printer seems to be underused to me. i would like more reading material on its use, including working examples from the past of neat uses.
14:02:39
jackdaniel
after investigating, and confiring with a second and a third implementation I was amused - the form was not expanded
14:03:43
jackdaniel
after throughful investigation, and narrowing the test case to 10 lines of the code I've found it! a stray backquote at the end of the macro that looked exactly like 100 other pieces of dust on my monitor
14:04:52
jackdaniel
(emacs colored this stray backquote in bronze and that matches the color of dust when highlighted by sun here, and makes it very blendable into the background)
14:05:01
Nilby
jackdaniel: lol, I've had the same thing happen, with a comma vs a dot and piece of dust in just the right place.
14:06:43
Nilby
Now I have a weird habbit of cleaning my screen when I'm tired and I get a macro bug.
14:21:45
_death
there was an old (Lisp Pointers?) article on pretty printing Lisp to a Pascal-like.. there's also http://norvig.com/ltd/doc/tool.html#inside2 which I've not yet looked into much
14:24:40
_death
and SBCL has pretty printer rules for CL operators, though sometimes in the cryptic format notation :/
14:30:36
_death
there's also a reference there to the lisp->pascal example, but the link is broken.. so https://www.researchgate.net/profile/Richard-Waters/publication/242313131_Using_the_new_common_Lisp_pretty_printer/links/02e7e533effb0d1006000000/Using-the-new-common-Lisp-pretty-printer.pdf
14:37:51
lukego
that old Waters article on Lisp->Pascal is by far the best example usage of PPRINT that I've seen
14:38:15
lukego
but it still takes me at least 20 tries to use ~< correctly in a format string and I usually give up before that point...
14:40:31
_death
since it's part 2, there must be a part 1: https://www.merl.com/publications/docs/TR91-04.pdf
14:44:34
Nilby
heh, I probably dodn't need to know more test frameworks, but RT is actually still used in places
14:48:45
_death
I wonder why no one writes an actual regression tester that stores the results the first time (or when told to) and compares to the new results.. I wrote something like that to test my solutions to puzzles like advent of code and rosalind (though I didn't store the results automatically).. then it can be extended to also test performance regressions
14:51:59
Nilby
I suppose for many things the results are t/nil, but beach was talking earlier about his markov chain fuzzer style testing.
14:54:54
beach
Nilby: No, nothing fuzzy. It is just that I need for the same kind of operation to be repeated with some significant probability, like INSERT for instance. Otherwise, the Flexichain will forever remain short and the resizing operations won't be sufficiently tested.
14:55:01
_death
you can also keep the seed.. I can imagine a counterargument about sampling the problem state anew each time, but then maybe that means your samples are too small/uniform
14:57:59
Nilby
Hmmm. I guess randomized valid input isn't exactly the same as fuzzing with random invalid input.
15:00:50
Nilby
It's like those joke random sentence generators running the parser backwards, but with AMB or something.
15:19:19
nij
Suppose I have a list of READable stuff. Is there a package that helps me edit this list by editting its content through an emacs buffer?
15:28:43
beach
I assumed you meant what you normally do in an Emacs buffer, like inserting and deleting characters.
15:31:54
lukego
_death: I've written a performance regression tester a bit like that. spends hours running permutations of configurations and workloads on a system, collects all the data in a big CSV, allows you to do e.g. ANOVA to compare different software versions and say "hmm config option FOO is really slowing down workload BAR in the new release"
15:33:57
lukego
even hooked it into a CI that would automatically detect performance regressions. that was fun.
15:42:04
_death
lukego: very cool.. I remember a post from a year ago about boinkmarks.. wonder what sbcl uses nowadays
15:43:10
lukego
beach: Hey, humble idea to borrow a leaf from your testing book, I realize that when I'm converting data from text to objects then an easy way to get testability might be just having a canonical print routine to turn it back to test. then I can e.g. (assert (string= (tostring x) (tostring (fromstring (tostring x)))) to differentially test the printer and reader against each other
15:44:19
lukego
so for example if I goofed and put a value in the wrong slot it'd be caught automatically, without me having to manually create examples with tests that know exactly how the object representation should look
16:29:57
nij
Now the only problem is to lispily format a long list such that the length of each row isn't more than, say, 80.
16:53:31
Nilby
I usually use with-output-to-string in a loop. You could also just output to a string with a fill-pointer.
16:56:30
Nilby
e.g. (let ((s (make-array 0 :element-type 'character :fill-pointer t))) (loop for i from 0 to 10 do (format s "salmon")) s)
17:42:32
shka_
(with-output-to-string (stream) (loop for i from 0 to 10 do (format stream "salmon")))
17:42:39
shka_
jmercouris: reduce is a really bad option here since concat will allocate new copy fo string for each element of the sequence being reduced
17:43:07
shka_
also, technically speaking function passed to reduce should handle being called with 0, 1 or 2 arguments
17:46:17
Nilby
The format one is slower actually than the reduce, but takes much less memory, but the with-output-to-string seems the fastest.
17:49:02
_death
shka: they will never be called with one argument, and you can provide an initial value to ensure they will never be called with no arguments
17:50:04
Alfr_
... or ensure that sequence is never empty, then it won't be called with zero arguments as well.
18:32:10
jasom
with-output-to-string is definitely the idiomatic way to accumulate values into a string.
18:36:32
fiddlerwoaroof
jmercouris: (reduce (lambda (acc next) (format acc "~a" next)) seq :initial-value (make-array 10 :element-type 'character :fill-pointer 0))
18:37:27
fiddlerwoaroof
Reduce is just a loop with an accumulator, so if you control the initial value there's no reason not to mutate it :)
18:38:25
fiddlerwoaroof
If some FP purist complains, just explain that you're using dynamic linear types.
18:38:36
jasom
fiddlerwoaroof: but at that point why use reduce at all, and just put the mutation in the loop body?
19:08:03
wanko
hello, is it okay to ask beginner scheme questions here, or is there a different channel for that?
19:46:43
dbotton
I assume there is no way in lisp to "use" the sequence passed to subseq as part of an expression to calculate end?
19:47:57
jasom
dbotton: I think various utility libraries let you do python-style passing of negative values for subseq ranges. I can't speak to the quality of any of them though.
19:48:22
Xach
dbotton: (defun trim-last-char (s) (subseq s 0 (1- (length s))) is what i might do if i didn't a cluttered expression
20:00:29
jasom
fiddlerwoaroof: but the original question was phrased in a way that assumes the sequence was of at least length 1
20:06:30
Bike
oh, i thought maybe sbcl might do its magic shrink-vectors-even-if-they-don't-have-fill-pointers thing but i guess it's too messy
20:54:36
dbotton
From a GitHub discussion "Clog is totally fun. It made me re-start learning Lisp." Thought I would share for those that help me
21:00:09
alanz
I know, which is why I am speaking up. I love seeing it come together bit by bit, and appreciate the effort you put in to making clear, understandable code
21:13:48
alanz
dbotton, I got as far as using your tutorial 13 as a base. Now scratching my head wondering what the next thing to do is. The general idea is to help managing entries to https://www.facebook.com/saflowerunion/posts/4851293668246422
21:18:54
dbotton
Since an admin tool, maybe consider using tutorial 22 as your base and have a nice look desktop motif
21:20:30
alanz
thanks, will do so. I also see myself interacting with the local file system, and showinng pictures. So the desktop one is definitely a good basis
21:21:53
alanz
its going to be slow though, this is a back-burner project for me, which I am using to learn cl at the same time (from some experience with elisp)
21:26:08
dbotton
And that is why my plan is to do a CLOG Lisp tutorial, it is a cool way for people to learn because they see results right away
21:27:25
dbotton
Still hope someone with better language skills takes me up on project :) but if not I will do
21:35:52
alanz
you are doing fine, as far as I can see. Being active and enthusiastic is the most important thing, I reckon