[Openmcl-devel] Obfuscated Lisp contest anyone? (Seriously)
Tim Bradshaw
tfb at tfeb.org
Sat Apr 15 08:16:01 PDT 2023
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.
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.
--tim
> On 15 Apr 2023, at 15:38, Tim McNerney <mc at media.mit.edu> wrote:
>
> Heck… A whole course could be taught on coding style.
>
> One entertaining source of counter examples is the Obfuscated C contest.
> (Perhaps there are others).
> I’m mostly attracted by functionality implemented in ridiculously small amounts of code.
> It makes me do silly things like de-obfuscation (macro-expansion, reformatting, etc).
> Maybe other people in this group have tried their hand at this too.
>
> Hmm… Is it crazy to contemplate launching an obfuscated Lisp contest?
> I would volunteer to be a judge. We’d want more than one, of course.
>
> --Tim
>
>>> On Apr 15, 2023, at 10:10, Tim McNerney <mc at media.mit.edu> wrote:
>>>
>> I wouldn’t fret Arthur.
>> The scope of declarations is a known weakness of Common Lisp (at least to me).
>> I have found other syntactic situations where, whether in practice or by spec, it is impossible to declare variables.
>> Declare ignore in destructuring-bind and multiple-value-bind come to mind.
>>
>> An effort to tighten this up might gain CCL an improved reputation.
>> For this to have an effect on portability might need a committee and commitment from other maintainers.
>> At least ignore declarations only affect compiler warnings.
>> It had honestly never occurred to me to use MV-bind on special variables.
>>
>> I wonder if anyone has written a Lisp style guide. (Or how many and from where, if so).
>> There are certain things I just never do, but the “rules” are in the attics of my mind.
>> There is certainly a subset of the language that falls within “good practice” for readability.
>> 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.”
>>
>> --Tim
>>
>>>> On Apr 14, 2023, at 19:54, Arthur Cater <arthur.cater at ucd.ie> wrote:
>>>>
>>> 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.
>>>
>>> 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
>>>
>>> LET** provides a syntax for easily combining functionality of LET* and MULTIPLE-VALUE-BIND.
>>> Anything you can say to LET* you can say to LET**, the converse is not true.
>>> …...
>>>
>>>
>>> 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.
>>>
>>> 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”.
>>>
>>>
>>>
>>>> On 14 Apr 2023, at 22:01, Tim Bradshaw <tfb at tfeb.org> wrote:
>>>>
>>>> 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.
>>>>
>>>> It is possible to check this :
>>>>
>>>> (let (c)
>>>> (let ((x 1)
>>>> (x (progn (setf c (lambda () x)) 2))
>>>> (declare (special x))
>>>> (values c (lambda () x))))
>>>>
>>>> (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...
>>>>
>>>> --tim
>>>>
>>>>>> On 14 Apr 2023, at 21:17, Arthur Cater <arthur.cater at ucd.ie> wrote:
>>>>>
>>>>> I can only find a define-compiler-macro, I want to see how LET* handle declarations.
>>>>> It surprises me that it is apparently legal to say
>>>>>
>>>>> ? (let* ((it 7) (it (list it it)) (it (length it))) it)
>>>>> 2
>>>>> ?
>>>>>
>>>>> and I wondered how declarations (if present) are treated - but I can’t find the source code.
>>>>>
>>>>> TIA for any hep
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20230415/47341534/attachment-0001.htm>
More information about the Openmcl-devel
mailing list