freenode/#lisp - IRC Chatlog
Search
17:40:13
verisimilitude
I recall reading some email archive from around thirty years ago on how Guido van Rossum was unwilling to make some changes to Python that would make it quality as equivalent to Scheme, I suppose because he wanted to maintain more control over his pathetic and horribly-designed language.
18:00:54
dim
I'm not sure why buildapp / Quicklisp are giving me a hard time these days ;; loading system "pgloader" Fatal MISSING-DEPENDENCY: Component #:CL-LOG not found, required by #<SYSTEM "pgloader">
18:05:01
dim
it's like my Makefile arrangements are not loading/downloading QL systems from/to the right place, actually
18:07:27
dim
was there a change recently in Quicklisp in where to look for systems? it looks like my used-to-be self-contained quicklisp installation is happy to find systems in my user's quicklisp directory
18:19:15
glv
The problem came from the fact that the systems.txt file of the quicklisp distribution was missing some systems/packages/dependencies
18:21:26
glv
I don't know if this file is generated locally or if it is shipped as-is with the quicklisp distribution...
22:39:30
wglb
It works for me almost all the time but if I ask it to parse http://www.databaseanswers.org/data_models/, it runs out of stack. It is trying to parse what looks like mis-classified content type.
22:40:49
wglb
If you can give it a try if you still have it available at your fingertips, just do a dex:get on that.
22:44:04
hjudt
sbcl x64-64. though the content it gets has strange characters between every character. perhaps ms-iis encoding problem?
22:46:15
solrize
"Common Lisp's FORMAT function is--along with the extended LOOP macro--one of the two Common Lisp features that inspires a strong emotional response in a lot of Common Lisp users. Some love it; others hate it.1" -- Peter Seibel. question: what if anything is there to use instead?
22:48:05
aeth
solrize: DO, DO*, DOTIMES, DOLIST, MAP, MAPCAR, REDUCE, etc., can be used as alternatives to LOOP.
22:48:55
sjl_
for FORMAT, there's all the write-* print-* stuff built in, or cl-interpol, or that one macro from that one guy's utility lib
22:49:07
aeth
solrize: FORMAT is the highest level of printing, but you can also use PRINC, PRINT, PPRINT, PRIN1, WRITE, TERPRI, WRITE-CHAR, WRITE-LINE, WRITE-SEQUENCE, etc.
22:49:49
aeth
Of course, you can mix and match printing because format writes to a stream, so anything other than FORMAT NIL (which writes to a string instead) can mix and match with multiple different ways to write/print to a stream.
22:50:11
aeth
If you have to generate a string with more than just FORMAT NIL you can use with-output-to-string
22:51:06
wglb
anamorphic: Hmmm. I abaondoned drakma because it gave me some issue that maintainer could not reproduce. I guess I should go try it on my freebsd system.
22:54:47
wglb
hjudt: I get total binary--strings on the resultant file shows nothing. Sounds like something is borked about this system I am running it on. Otherwise, it works well enough to parse on the order of a million other pages with no problem.
22:58:36
solrize
aeth thanks but what if you want to format a float or something like that? also what do you use instead of LOOP, other than e.g. LABELS ?
22:58:47
hjudt
wglb: i have not encountered any such difficulties with dexador yet, it usually selects the proper methods according to the content type. drakma however often required to do conversions with flexi-stream
22:59:11
aeth
< aeth> solrize: DO, DO*, DOTIMES, DOLIST, MAP, MAPCAR, REDUCE, etc., can be used as alternatives to LOOP.
23:00:29
aeth
solrize: If you want to use something that only format can do (without building your own function from scratch), you can still mix and match format with other things and just e.g. (format stream "~G" float) while using prints/writes everywhere else.
23:02:01
aeth
solrize: e.g. (let ((stream *standard-output*)) (write-string "Hello, user " stream) (format stream "~F" 42d0) (write-char #\! stream) (terpri stream))
23:02:29
aeth
Obviously they default to standard output so that was unnecessary to get that particular example to run. Imagine it in a function instead, though.
23:04:02
solrize
aeth i guess FORMAT isn't so bad if you use it like printf i.e. without too much programming inside the format string. but i didn't see a simple way to write a "while" loop with e.g. DOTIMES
23:04:59
aeth
solrize: You have to use DO for that, or manually write your own macro on top of TAGBODY and GO (which essentially gives you a goto limited to be inside of one form).
23:05:56
solrize
is it considered uncouth to just use tail recursion and assume the compiler does the right thing? i'm using sbcl
23:06:12
aeth
Iirc, DO is basically an until loop (not while, but you just negate the terminating condition) with a LET at the top, with an optional increment-every-time step added to the end of each LET binding. DO* is the same, but with LET* instead of LET.
23:06:41
sjl
something like (defmacro while (condition &body body) `(do () ((not ,condition)) ,@body))
23:07:03
aeth
Tail recursion depends on the implementation and on the optimization levels in the implementation. Iirc, you can't expect it with (debug 3) in SBCL. It's a bit of a shame that there isn't finer control over whether to turn on and off a feature afaik.
23:07:45
solrize
yeah that's what i did, saw a loop example and followed it (though i used (loop while ... do) without :while
23:08:24
sjl
I use keyword symbols because they stand out more to me visually, but a lot of other folks use normal ones
23:09:27
aeth
I use keywords because keywords are highlighted by the editor without requiring the editor to have a special syntax highlighting mode that parses each LOOP.
23:10:33
aeth
Another advantage of keywords is that you use :=, which clearly distinguishes it from =, which usually means equality in Common Lisp.
23:11:26
aeth
The final, and probably smallest, advantage is that you don't "pollute" the symbols in your package by creating a bunch of symbols that are only used for that LOOP.
23:14:40
aeth
LOOP is a lot more necessary than FORMAT. There is no equally-concise way to do something like a conditional collect/append outside of LOOP built into the language. You can use a library, but then you're using a library.
23:16:05
aeth
Oh, and it's harder to mix and match things with LOOP than it is with FORMAT (where you can just use it like any other print/write function). You really can't, except when you have inner/outer loops, which obviously can be something other than a loop that uses LOOP.
23:16:55
aeth
My main problem with ITERATE (besides how it handles symbols for its forms) is that it's not compatible enough with LOOP, possibly because it was probably written before LOOP "won".
23:17:49
aeth
I want something Lispier, but I literally just want a DO-LOOP that is LOOP with s-expressions around its forms so I can say something like (do-loop ((:for foo :in bar)) ...) or (do-loop (:for foo :in bar) ...) depending on how the actual API details work
23:18:45
aeth
Of course, this probably would require writing a from-scratch portable implementation of the LOOP macro because LOOP itself isn't extensible so the naive just-compile-it-down-to-LOOP approach would cause issues.
23:20:19
sjl
maybe you're thinking of https://common-lisp.net/project/iterate/doc/Don_0027t-Loop-Iterate.html
23:22:38
solrize
yeah there's some stream fusion methods so you can cons like crazy and the compiler eliminates the conses
23:23:39
_death
no need to succumb to knee-jerk anti-loopism, just read https://adeht.org/usenet-gems/one-function.txt
23:29:58
solrize
does COLLECT typically build the list backwards then nreverse, i.e. just wallpaper over that idiom?
23:31:16
White_Flame
I would assume that mature implementations tack on a new cons cell to the tail of the list, for performance
23:32:40
sjl
especially since you have to make the list available in the right order during iteration if the user binds it to a var anyway, right?
23:32:46
solrize
yeah i guess that would be a bit faster, it overwrites the same amount of cdr's but avoids some memory hits
23:33:08
sjl
e.g. (loop :for i :from 1 :below 10 :collect i :into l :do (print l)) would have to nreverse twice on every iteration or something
23:35:48
White_Flame
I'm not sure you can. " If into is used, the construct does not provide a default return value; however, the variable is available for use in any finally clause. "
23:39:00
sjl
I guess you can read that as "ONLY available for use in any finally clause", yeah. yet another reason I use iterate more, hah
23:41:22
sjl
oh, > During each iteration, the constructs collect and collecting collect the value of the supplied form into a list. When iteration terminates, the list is returned. The argument var is set to the list of collected values; if var is supplied, the loop does not return the final list automatically.
23:41:23
_death
not that I can see, but it does say you can accumulate multiple times into the same destination
23:42:12
White_Flame
right, but what's the readable scope of that variable? only finally is mentioned, but as you note it's not exclusively worded
23:42:32
_death
if you can, then it's interesting that you can create a circular list that way.. (loop repeat 2 collect foo into foo finally (return foo))
23:46:33
White_Flame
hmm, (loop for x from 1 to 10 collect (list x y) into y) just returns NIL for me, no error
23:49:25
sjl
setting *print-circle* will tell lisp to spend some more effort during printing to detect circular structures and avoid choking on them
23:50:42
sjl
Doesn't seem super surprising... it's collecting into a list. Each iteration, it adds a two-element list onto the end of the list. That two-element list happens to contain the original list in this case.
23:51:51
sjl
yeah after reading 6.1.3 I'm 90% sure it has to work like I originally thought to be compliant
23:56:08
White_Flame
the original question I was looking at is if it would be able to push & nreverse, but I think this would make that too heavyweight and basically forces appending to the tail
23:58:41
_death
solrize: (defun collatz (n) (loop for k = n then (if (oddp k) (1+ (* k 3)) (floor k 2)) and prev = 0 then k until (= prev 1) collect k))
0:00:47
sjl
obligatory overengineered iterate version https://github.com/sjl/euler/blob/master/src/utils.lisp#L573-L588 :)
0:34:54
sjl
the other headings are right because I gen them with a keybind... it's just the one that my idiot self typed by hand that's hosed
2:30:49
ahungry
Does scheme have something similar to a plist in CL or a map in Clojure? A simple way to get a field out like (getf '(:x 1 :y 2) :x) => 1 - I know of assoc - I guess I could write a wrapper to get the cadr of one
2:32:37
ahungry
Seems that wouldn't really solve my want of having a simple literal format for the data though, so I'd probably just have to make something that walks a list 2 atoms at a time and stops if the first matches my lookup
2:38:35
p_l
ahungry: not sure how standard it is, but: https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-html/scheme_12.html
3:03:43
solrize
ahungry, there's some srfi's for all kinds of stuff like that... #scheme would know more
3:05:38
aeth
specifically, jcowan will know more about Scheme implementation support of $feature in #scheme
4:11:29
fiddlerwoaroof
In terms of LOOP alternatives, there's also https://github.com/Shinmera/for, which I prefer to iterate, if I'm going to use a library