freenode/#lisp - IRC Chatlog
Search
11:43:31
jackdaniel
complex float operations improvements in ECL: http://hellsgate.pl/files/2542707e-report.html (no optimizations in compiler yet whatsoever, just generic dispatch on math operations). still behind sbcl though :c
11:44:28
jackdaniel
mandelbrot/dfloat is put there for scale, we should do much better job with double floats too
13:29:51
jackdaniel
I've put results in clim app: https://imgur.com/drAprZJ.png (numbers are little different - I've run it again and removed dfloat)
13:55:51
mgsk
I have some dir `./src/contribs` that contains things like plugins that depend on the main library. I want these to be loaded whenever the main library is loaded. Is this something that ASDF can deal with?
13:56:40
mgsk
I guess just doing `(:file ...)` would suffice in that case. I was expecting something more complicated
13:57:13
mgsk
e.g. I don't know ahead of time what is in the contribs dir, so I can't write out all the appropriate `(:file ...)`forms.
13:58:07
jackdaniel
a few months back I wrote an "autodiscovery" module class for someone, link should be somewhere in logs
21:07:37
vms14
I have no idea how to convert a string to a list of symbols, I just take the first element
21:09:48
aeth
vms14: So the problem is that you're reading in a line into a string, and you're turning "Hello world" into |Hello world| instead of (HELLO WORLD)
21:11:17
vms14
I'm trying to parse input, I just want read every symbol from the input until the user press enter
21:13:37
aeth
vms14: One thing you could do, and it's quite a hack, is (read-from-string (read-line))
21:13:53
vms14
the thing is usually I won't know how many symbols will be, and the delimiter is the newline
21:14:04
aeth
vms14: the second value in read-from-string is where it left off so you can loop on that second value
21:14:25
pjb
vms14: or: (loop for element = (extract-one-item (read-line)) until (eof-element-p element) collect element)
21:15:03
pjb
vms14: using READ or READ-FROM-STRING, you allow input to do whatver it wants with your lisp image, by default.
21:15:11
aeth
vms14: (read-from-string (read-line)) for a line "hello world" will return (values HELLO 5)
21:16:30
aeth
vms14: you can then do (read-from-string (read-line) nil nil :start 5) to get (values WORLD 11)
21:16:53
pjb
So you would want to bind *read-eval* to NIL. but other reader macros can be problematic: (read-from-string "#8931289312839012*") for example, could DOS your system by trying to allocate all its RAM. (or just signal a condition, depending on the implementation).
21:17:19
pjb
another thing is that reading symbols will intern them, so if there's a loop, the input could fill your memory with useless symbols.
21:17:47
pjb
So you might want to intern the symbols in a throw away package that you can delete-package when you're done.
21:17:47
aeth
vms14: The "correct" (safe) way to do things is to parse the string, perhaps with cl-ppcre
21:18:15
aeth
By the time you add in the validation pjb is talking about, the parse solution probably becomes more concise than the elegant solution that pjb and I both said simultaneously
21:18:57
pjb
vms14: (split-sequence #\space (read-line) :remove-empty-subseqs t) is usually all you need.
21:19:36
aeth
Which to use is debatable. split-sequence is a smaller dependency, but if you're doing additional parsing, you might be using cl-ppcre anyway
21:19:40
pjb
(ql:quickload :split-sequence) (use-package :split-sequence) (with-input-from-string (*standard-input* "Hello world! How do you do?") (split-sequence #\space (read-line) :remove-empty-subseqs t)) #| --> ("Hello" "world!" "How" "do" "you" "do?") ; 27 |#
21:21:23
aeth
If you wanted "absolutely 0" overhead, you can get that. Well, not quite 0, you'd have to track start and end positions for each substring. String/sequence functions take in start and end so you can just work like that.
21:22:50
pjb
(com.informatimago.common-lisp.cesarum.array:positions #\space "Hello world! How do you do?") #| --> (5 12 16 19 23) |#
21:24:58
pjb
(let ((string "Hello world! How do you do?")) (loop :for start := 0 :then (1+ end) :for end :in (com.informatimago.common-lisp.cesarum.array:positions #\space string) :collect (cons start end) :into result :finally (return (nconc result (list (cons end (length string))))))) #| --> ((0 . 5) (6 . 12) (13 . 16) (17 . 19) (20 . 23) (23 . 27)) |#
21:25:07
aeth
You could store positions in an array with the :element-type alexandria:array-index, which will probably round up to fixnum or "unsigned fixnum" (it will show up as some strange looking unsigned-byte size like (unsigned-byte 62)) or (in 64-bit implementations) (unsigned-byte 64)
21:25:43
pjb
And then you can use (foo string :start (car pos) :end (cdr pos)) with most sequence functions to process the substrings. Or (subseq string (car pos) (cdr pos)) when you need to extract it.
21:28:18
aeth
You could also do that as two vectors or two lists, one for start position and one for end position. (I think to make the vector, the best solution would be to walk the string twice, first to get the length for the allocated vectors and then to set the elements)
21:28:21
pjb
vms14: Notice that displaced arrays just abstract those (car pos) (cdr pos) bounds. So instead of subseq, you can use (make-array (- (cdr pos) (car pos)) :element-type (array-element-type string) :displaced-to string :displacement-offset (car pos))
21:31:21
aeth
the alternative is to allocate a list or vector of positions, or, as I recently noticed, two sequences instead of one
21:34:57
aeth
splitting isn't the standard way to think about things, the standard way to think about things is with positions, which is why every built-in (and every well-behaved library) has start/end or start1/end1/start2/end2
21:36:55
aeth
the easiest no-library way to do it is probably read-line and do position tracking, but read-char will probably be the most efficient solution