libera/commonlisp - IRC Chatlog
Search
0:36:02
jasom
Then once you've done that, you need to ensure that the "optimize" declaration is set sufficiently high (in either the absolute or relative sense; some compilers may use the relative values of optimize v. debug, for example)
0:38:01
jasom
The one place I like to rely on TCO is when implementing state-machines; in that case the non-tail call approach is less readable IMO and will involve passing either closures or a list of function and arguments, both of which are more unweildy than a tail-call
0:39:20
jasom
I should also point out that non-tail-recursive code is *definitely* non-portable; the maximum recursion depth may vary not just from implementation to implementation, but from machine to machine even when using the same implementation
0:46:10
neominimum
Ok, so it's definitely not feasible in some situations due to environmental factors and the use of some language features.
0:50:36
neominimum
I do like recursion, more because I find it challenging. To me it definitely looks better than some iterative implementations sometimes, but as they say "When in Rome..."
0:51:32
jasom
Oh, there are times when recursion is more readable than iteration, but, in my experience, few of those cases are tail-recursive
0:52:08
jasom
The most obvious example is any sort of tree walker; the recursive form is almost trivial, the iterative form involves an explicit stack.
0:54:26
jasom
The naïve fibonacci is the most readable way to do fibonacci; I think the iterative vs. tail-recursive are of similar readability.
0:56:36
EdLangley[m]
Clojure's LOOP/RECUR is an example of an abstraction that makes this a bit nicer.
1:03:34
EdLangley[m]
If you (psetf arg1 (step arg1) arg2 (step2 arg2)) (go start) you can "pass arguments"
1:04:40
jasom
EdLangley[m]: right, but that's far less clear and sm2n was asking "why not use tagbody"
1:05:19
neominimum
If I understand correctly now. In the iterative form, walking a non-linear data structure, requires the use of an explicit stack. Compared to the recursive form utilising the implicit call stack.
1:05:24
jasom
also if you break in the middle of the state-machine, you more quickly get the information you want with most implementations it will show the current function
1:06:50
jasom
neominimum: right, my comment was that most of the times that recursion is more clear than iteration, it's due to the implicit call-stack, which means it's not a tail-call.
1:07:18
EdLangley[m]
Hmm, expanding to (defun foo (...) (macrolet ((foo () `(go start))) (tagbody start ...))) would mean you could just turn recursive calls into GOs
1:08:20
jasom
EdLangley[m]: at that point I'd rather just do a loop/apply/funcall and return a function/args list from each state
1:09:19
EdLangley[m]
I've used it in PHP before when the recursive version of a function was significantly easier to write than the iterative one.
1:09:43
jasom
I've done both and I find the tagbody gets unweidly quickly for complicated state machines
6:33:14
asarch
If you have: '(:beers 20 :tacos 3), how would you add the property :pizza 4 to the list?: (:beers 20 :tacos 3 :pizza 4)
6:34:21
asarch
(push :pizza *the-list*) (setf (getf *the-list* :pizza) 4) overwrites a property name: (:pizza 4 20 :tacos 3)
6:36:08
mfiano
The problem might be the original question made a literal list as its example to be mutated.
6:36:13
moon-child
this will behave slilghtly differently to beach's suggestion, if pizza happens to already be contained within the property list
6:41:22
beach
asarch: Also, I would start using more interesting food examples, like :SUSHI, :MAGRET-DE-CANARD,
8:32:00
beach
DEFCONSTANT means the compiler can substitute the value for the name when references are compiled.
8:32:01
phoe
with constants, the compiler doesn't need to do variable access, it is allowed to splice literal constant values wherever the constant is used
8:32:33
phoe
and that means no global value lookup and no dynamic binding lookup, which speeds things down, and that the compiler can always figure out the type of the value ahead of time
8:58:19
lisp123
I was thinking of this idea, let me know if there are any flaws in it: I USE a package, say CLIM, and then I don't use any package qualifiers.
8:58:56
lisp123
Later on, I run a function that reads a file, and adds package qualifiers for all symbols not in the current-package or in CL
9:00:40
phoe
adds package qualifiers? as in, it reads a Lisp file and prints back out package-qualified symbols wherever applicable?
9:01:34
beach
lisp123: Certain re-evaluations of the DEFPACKAGE form with different options exposes undefined behavior.
9:02:05
beach
lisp123: And why would you intentionally make life harder for the person reading your code by omitting package prefixes the first time around?
9:02:15
lisp123
It would be outside of the Lisp Image / System. As in destructively modify the file to add in package prefixes
9:03:06
lisp123
Not having to write package qualifiers while I'm developing. And once I'm "done" M-x insert-package-qualifiers
9:03:57
beach
lisp123: So you mean, you magically add package prefixes to all your imported symbols later on?
9:04:29
phoe
mostly because wouldn't trust myself that I'd tell it to get all package qualifiers right
9:05:36
phoe
this, plus I generally dislike the :USE option because is dangerous even if you get all package qualifiers right
9:06:51
lisp123
beach: Yes. So I would manually remove the :USE option before reloading the files (including packages.lisp), although I'm sure there would be a way of finding the defpackage form then destructively modifying the file
9:07:49
lisp123
This is basically like a clean up exercise, not meant to be part of the image. Just to save having to type package prefixes during development
9:08:22
beach
lisp123: So if you accidentally use an imported symbol as a lexical variable, this symbol is going to have a package prefix later?
9:09:08
lisp123
So if you accidentally use an imported symbol as a lexical variable, this symbol is going to have a package prefix later? -> Thanks
10:00:41
chrnybo
I'm golfing on parsing four letters in a-z into a single number; is there a "shift left and add" operation in CL?
10:03:46
moon-child
beach: shift and add can be conceived of as a unitary 'append digits' operation. Most things can be decomposed; that does not mean it is not worthwhile to think of them as atomic in some context
10:05:13
beach
moon-child: Do you have a Common Lisp operation that will do both? I can't think of any.
10:07:41
moon-child
that was not how I interpreted it. chrnybo asked 'is there a "shift left and add" operation in CL?' Your response I interpreted as 'that is not an operation, but two', not 'CL has no such operation'
10:13:35
beach
chrnybo: There is not a single Common Lisp operator that will do both those operations. So in Common Lisp you need to use two operators to achieve the effect you want.
10:43:19
beach
chrnybo: You did not include digits in your possible characters, so it was not clear that your letters meant the same as they do in Common Lisp.
12:22:12
semz
I don't think optimizing this for runtime is worth it unless your list is huge (in that case a hash table would be a good idea)
12:27:25
lisp123
semz: Because its a low-level function I need (a varaint on ALPHANUMERICP), optimisation is important
12:29:58
lisp123
I'll use a Hash Table for now, unless someone has a better idea. I assume the char-codes were ordered in a way that allowed SBCL and other implementations to use an array
12:30:07
pjb
lisp123: in general the fastest would be to index a vector giving the answer: (aref answer (char-code ch))
12:31:01
pjb
lisp123: since character sets are usually small (less than 256), a bit-vector would be quite small (only 32 bytes, less than a hash-table memory overhead!)
12:31:38
pjb
lisp123: but if you consider unicode, then the bit-vector will have to be bigger: 139264 bytes.
12:31:41
lisp123
pjb: Thanks. Looking again at the SBCL code, now I suspect they may be doing the same thing you suggest
12:31:48
semz
That too depends on the exact set though. Honestly I suspect that optimizing this is a waste of time, but I don't know what lisp123 is using it for.
12:33:02
lisp123
semz: I have to search for next word in an editor command I am writing, without using the underlying version of Emacs / whatever
12:34:38
lisp123
Or go to the next paragraph (which has much more characters to search through). And I don't want to keep a history of start/end points since they can change if the buffer changes