<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div dir="ltr"></div><div dir="ltr">I always used to answer obvious homework questions on cll by turning all binding constructs into equivalent lambdas and then using the U combinator (which I did not know was U at the time as I'd rediscovered it myself) to express recursion as opaquely as possible. Any iteration was obviously expressed as recursion.</div><div dir="ltr"><br></div><div dir="ltr">This is much easier in Scheme, as all the funcalls get annoying in CL. Creative use of call/cc is also a great advantage of course.</div><div dir="ltr"><br></div><div dir="ltr">--tim</div><div dir="ltr"><br><blockquote type="cite">On 15 Apr 2023, at 15:38, Tim McNerney <mc@media.mit.edu> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><meta http-equiv="content-type" content="text/html; charset=utf-8">Heck… A whole <i>course</i> could be taught on coding style. <div><br></div><div>One entertaining source of <i>counter examples</i> is the Obfuscated C contest.</div><div>(Perhaps there are others).</div><div><u>I’m mostly attracted by functionality implemented in ridiculously small amounts of code.</u></div><div>It makes me do silly things like de-obfuscation (macro-expansion, reformatting, etc).</div><div>Maybe other people in this group have tried their hand at this too. </div><div><br></div><div><b>Hmm… Is it <i>crazy</i> to contemplate launching an obfuscated <i>Lisp</i> contest?</b></div>I would volunteer to be a judge. We’d want more than one, of course.<div><br><div dir="ltr">--Tim</div><div dir="ltr"><br><blockquote type="cite">On Apr 15, 2023, at 10:10, Tim McNerney <mc@media.mit.edu> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><meta http-equiv="content-type" content="text/html; charset=utf-8">I wouldn’t fret Arthur.<div>The scope of declarations is a known weakness of Common Lisp (at least to me).</div><div>I have found other syntactic situations where, whether in practice or by spec, it is impossible to declare variables. </div><div>Declare <i>ignore</i> in <b>destructuring-bind</b> and <b>multiple-value-bind</b> come to mind. </div><div><br></div><div>An effort to tighten this up might gain CCL an improved reputation.</div><div>For this to have an effect on portability might need a committee and commitment from other maintainers. </div><div>At least <i>ignore</i> declarations only affect compiler warnings. </div><div>It had honestly never occurred to me to use MV-bind on special variables. </div><div><br></div><div>I wonder if anyone has written a Lisp style guide. (Or how many and from where, if so).</div><div>There are certain things I just never do, but the “rules” are in the attics of my mind. </div><div>There is certainly a subset of the language that falls within “good practice” for readability.</div><div>I know this is true with C++, because when I passed in function objects as arguments, my manager wrote in a review that my code was “too academic.”</div><div><br><div dir="ltr">--Tim</div><div dir="ltr"><br><blockquote type="cite">On Apr 14, 2023, at 19:54, Arthur Cater <arthur.cater@ucd.ie> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><span>Oh dear oh dear. I’m sorry I’ve opened a can of worms. I must apologise as I wasn’t looking at the spec, but at CLtL2 which clearly says LET* is a macro.</span><br><span></span><br><span>Personally, I’d never write the code I gave as an example. I totally agree with Shannon, it’s ugly. The reason I asked is because I thought it’d be handy to write a new macro for my own use, and offer it to others, provisionally called LET**. The doc string says</span><br><span></span><br><span>LET** provides a syntax for easily combining functionality of LET* and MULTIPLE-VALUE-BIND.</span><br><span>Anything you can say to LET* you can say to LET**, the converse is not true.</span><br><span>…...</span><br><span></span><br><span></span><br><span>So I wanted to make it true that "Anything you can say to LET* you can say to LET**", and this involves handling declarations the same way, and that involves understanding how LET* handles declarations, and that led to asking myself whether it was possible to bind the same name multiple times - thinking I understood LET* expanded into multiple nested LETs. CLtL2 didn’t say yea or nay, so I experimented and CCL said yea. What’s it doing then? What does it expand to? Let’s look at the macro expansion. What, it expands to itself??? Ask my openmcl friends.</span><br><span></span><br><span>And it looks like it’s a can of worms. Just yesterday I was amused to see in somebody’s blog a snapshot of the CLtL2 index “kludges, 1-971”. </span><br><span></span><br><span></span><br><span></span><br><blockquote type="cite"><span>On 14 Apr 2023, at 22:01, Tim Bradshaw <tfb@tfeb.org> wrote:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>I think this is surprisingly underspecified. I think the only sane answer is that declarations should apply to all the bindings of a given name in a given let* (or other sequential-binding) form.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>It is possible to check this :</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>(let (c)</span><br></blockquote><blockquote type="cite"><span> (let ((x 1)</span><br></blockquote><blockquote type="cite"><span> (x (progn (setf c (lambda () x)) 2))</span><br></blockquote><blockquote type="cite"><span> (declare (special x))</span><br></blockquote><blockquote type="cite"><span> (values c (lambda () x))))</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>(sorry for paren/indentation errors, I'm typing this on a phone). If the special declaration applies to both bindings then calling either function returned will be an error. If it applies to only one: which, and why, and why does nothing say? Either the spec simply omits this crucial information which would be a horrible omission, or the declarations apply to all the bindings. Or, quite possibly I've just missed the place where it *does* say...</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>--tim</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>On 14 Apr 2023, at 21:17, Arthur Cater <arthur.cater@ucd.ie> wrote:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I can only find a define-compiler-macro, I want to see how LET* handle declarations.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>It surprises me that it is apparently legal to say</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>? (let* ((it 7) (it (list it it)) (it (length it))) it)</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>2</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>? </span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>and I wondered how declarations (if present) are treated - but I can’t find the source code.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>TIA for any hep</span><br></blockquote></blockquote><span></span><br><span></span><br></div></blockquote></div></div></blockquote></div></div></blockquote></body></html>