Post AWI161If3PsavUcpuK by louis@emacs.ch
(DIR) More posts by louis@emacs.ch
(DIR) Post #AWHlB7bpQSNAfv09lA by galdor@emacs.ch
2023-06-02T15:48:41Z
0 likes, 1 repeats
Quick article about REDUCE in Common Lisp, its surprises, and a comparison with fold. Enjoy!https://www.n16f.net/blog/reduce-vs-fold-in-common-lisp/
(DIR) Post #AWI0e2ttVfkvmXhZZ2 by louis@emacs.ch
2023-06-02T18:41:59Z
0 likes, 0 repeats
@galdor Common Lisp has everything a functional language needs. Why in the world did they put a fully separate programming language into CL just for LOOP?It would be interesting to know more about the reasoning behind this and debates they had in the standards committee.
(DIR) Post #AWI161If3PsavUcpuK by louis@emacs.ch
2023-06-02T18:46:59Z
0 likes, 0 repeats
@galdor Great article btw.! Would be interesting to know if the behavior of REDUCE you describe is defined as such in the standard or just happens to work this way in (which?) implementation?
(DIR) Post #AWI3unArX6CdnEJcAK by galdor@emacs.ch
2023-06-02T19:18:36Z
0 likes, 0 repeats
@louis You could ask Kent Pitman about it. My understanding is that Common Lisp was a compromise between major Lisp dialects at the time. It's possible that one of them had LOOP and had the political clout to get it included (design by committee is wonderful).I only ever use the form without any argument when I want a simple loop without a clear stop condition.
(DIR) Post #AWI6YShJHeKNmGXIzw by galdor@emacs.ch
2023-06-02T19:48:11Z
0 likes, 0 repeats
@louis Just found some historical information:http://www.paulgraham.com/loop.htmlI completely agree with the conclusion.
(DIR) Post #AWIC5V8zhxXugz3it6 by screwtape@mastodon.sdf.org
2023-06-02T20:50:11Z
0 likes, 0 repeats
@louis @galdor++ as you mention, if you do not provide the :initial-value keyword, the result might be a different type than you are expecting. The convention is to always use the :initial-value keyword (I forgot which author I would cite for this; was it The Land of Lisp? Anyway it's conventional to always explicitly use :initial-value .
(DIR) Post #AWICv8BUJiWEXfqPgW by ksaj@infosec.exchange
2023-06-02T20:59:32Z
0 likes, 0 repeats
@galdor It is fun to point out to new Lispers that:(+ (+ (+ (+ 1 2) 3) 4) 5)is effectively the reverse of:(+ 1 (+ 2 (+ 3 (+ 4 5))))since the numbers vaguely appear to be in the same order.It's interesting that :from-end means "from the last two" instead of "from the last one" so it's not a true reversal. That can be seen more clearly if you do this with subtraction instead of addition.
(DIR) Post #AWIDZhuSuTrivTELSa by amszmidt@mastodon.social
2023-06-02T21:06:51Z
0 likes, 0 repeats
@louis @galdor Because LOOP predates much of Common Lisp, and was a normal construct (much like COND, TYPECASE, ...). Common Lisp was not designed as a functional language (but as an amalgamation of various Lisps), and it even lacks many of the things that purely functional languages have. LOOP wasn't a "fully separate language" it is an essential part of Lisp.
(DIR) Post #AWIDhdTXHSf7UQPmnA by amszmidt@mastodon.social
2023-06-02T21:08:19Z
0 likes, 0 repeats
@galdor @louis Should be noted that this is predates much, if not all of the CL process.
(DIR) Post #AWIFfhAOmk7yGdfMfI by screwtape@mastodon.sdf.org
2023-06-02T21:22:00Z
0 likes, 0 repeats
@louis @galdor actually, couldn't we just(Defun foldl (function value sequence) (reduce function sequence :initial-value value))in which case the ANSI standard would not introduce foldl, because it is a subset of reduce's behaviour. Hence(defun foldl (function value sequence &key &allow-other-keys keys) (apply 'reduce function sequence :initial-value value keys))
(DIR) Post #AWIFfhpALAjmJ4jvCy by louis@emacs.ch
2023-06-02T21:30:21Z
0 likes, 0 repeats
@screwtape @galdor I like this ruthless pragmatism 😎
(DIR) Post #AWIJlipNvDh0yOxyYi by amszmidt@mastodon.social
2023-06-02T21:02:30Z
0 likes, 0 repeats
@ksaj @galdor And that is exactly the same as (+ 1 2 3 4 5) ....
(DIR) Post #AWIJljZ7BCGxGEMUq0 by ksaj@infosec.exchange
2023-06-02T21:15:48Z
0 likes, 0 repeats
@amszmidt @galdor Here's an example of what I mean about from-end not being the same as an actual reversal:[1]> (reduce #'- '(10 3 14) :from-end t)21[2]> (- 14 3 10)1Here's the trace:(reduce #'- '(10 3 14) :from-end t)Trace: (- '3 '14)Trace: - ==> -11Trace: (- '10 '-11)Trace: - ==> 2121
(DIR) Post #AWIJlk6n9zD8wg7OKW by amszmidt@mastodon.social
2023-06-02T21:18:51Z
0 likes, 0 repeats
@ksaj @galdor
(DIR) Post #AWIJlkjmp0P2tcMX6u by ksaj@infosec.exchange
2023-06-02T21:21:47Z
0 likes, 0 repeats
@amszmidt @galdor Correct. Now ask a Lisp newb to explain the results from a reduce :from-end. Like I said, it's not starting from the last one, it's starting from the last two. It's not obvious the first time you try it.
(DIR) Post #AWIJllUa11pjEkFu2y by amszmidt@mastodon.social
2023-06-02T21:26:11Z
0 likes, 0 repeats
@ksaj @galdor Sorta depends, (reduce #'- '(10 3 14)) on the Lisp Machine raises an error -- where SBCL and such, return -7.
(DIR) Post #AWIJlm6rigST9UATiq by ksaj@infosec.exchange
2023-06-02T21:33:47Z
0 likes, 0 repeats
@amszmidt @galdor Interesting. Why does the Lisp Machine fail it?
(DIR) Post #AWIJlmn3BqCbGJuATY by amszmidt@mastodon.social
2023-06-02T21:35:21Z
0 likes, 0 repeats
@ksaj @galdor
(DIR) Post #AWIJlnTEezwjN9drEG by ksaj@infosec.exchange
2023-06-02T21:37:40Z
0 likes, 0 repeats
@amszmidt @galdor It can only reduce an even number of items? 🤯
(DIR) Post #AWIJloCbwIF5dss5xI by amszmidt@mastodon.social
2023-06-02T21:42:10Z
0 likes, 0 repeats
@ksaj @galdor Much worse, even for even numbers -- wondering if that is a bug now. It isn't like this is a very (or .. was) a common Lisp idiom.
(DIR) Post #AWIJlos5S5Q3iWHDbU by ksaj@infosec.exchange
2023-06-02T21:52:54Z
0 likes, 0 repeats
@amszmidt @galdor Does it work at all? What's the bare minimum list that you give it without error?
(DIR) Post #AWIJlpXCzCJRm3W3hQ by ksaj@infosec.exchange
2023-06-02T21:57:45Z
0 likes, 0 repeats
@amszmidt @galdor Just for fun I (successfully) gave it only one item:[21]> (reduce #'- '(4))4It literally takes zero items before you get the Lisp Machine error:[22]> (reduce #'- '())Trace: (-)*** - APPLY: too few arguments given to -The following restarts are available:
(DIR) Post #AWIJlq4sxzFdSVGxBw by galdor@emacs.ch
2023-06-02T22:16:14Z
0 likes, 0 repeats
@ksaj @amszmidt See http://www.lispworks.com/documentation/lw60/CLHS/Body/f__.htmThe - function requires at least one argument, while the + function accepts zero.
(DIR) Post #AWIK1oVMaAfhDJH4uO by ksaj@infosec.exchange
2023-06-02T22:19:10Z
0 likes, 0 repeats
@galdor @amszmidt Yup, that even works correctly on lowly old clisp. 😅
(DIR) Post #AWIKifQGE4KhUuK1L6 by screwtape@mastodon.sdf.org
2023-06-02T22:26:55Z
0 likes, 0 repeats
@louis @galdor it's explicitly part of the standard (perhaps surprisingly...)
(DIR) Post #AWIPEhYOEn23BrefSa by ghard@mastodon.social
2023-06-02T23:17:32Z
0 likes, 0 repeats
@galdor @louis YMMV but I’ve found LOOP to be just the concise DSL needed to process some aggregates iteratively at one go. Arguably ITERATE may be ”lispier” - whatever that means - but I choose to use the standard way since it’s minus another dependency.
(DIR) Post #AWIPlwpgS4TY8Kb53Q by ghard@mastodon.social
2023-06-02T23:23:31Z
0 likes, 0 repeats
@louis @galdor a very common set of use cases perhaps. TCO is not mandated by the standard, AFAIK, so iteration constructs that are concisely expressed should be a good thing. And to show off the malleability of the language and troll the paren haters?
(DIR) Post #AWJA3HJU9cC0T2jpwG by glitzersachen@hachyderm.io
2023-06-03T01:59:11Z
0 likes, 0 repeats
@amszmidt @louis @galdor then why does it feel so tacked on?
(DIR) Post #AWJA3I2rQuUMjly4fI by amszmidt@mastodon.social
2023-06-03T07:59:28Z
0 likes, 0 repeats
@glitzersachen @louis @galdor I don’t think it does? See FORMAT .
(DIR) Post #AWJA3IcJJ6qSViYNv6 by amszmidt@mastodon.social
2023-06-03T08:01:52Z
1 likes, 0 repeats
@glitzersachen @louis @galdor using DSL language is quite normal in Lisp. Adding () to everything doesn’t make it Lispier. (E.g, I prefer old style DO over new style DO)
(DIR) Post #AWJxEeny34JUGU3GCG by gothnbass@linuxrocks.online
2023-06-03T17:12:25Z
0 likes, 0 repeats
@galdor @louis "Common Lisp is politics, not art."~ Scott Fahlman
(DIR) Post #AWK3hKrnrA3yYCu66q by Ardubal@mastodon.xyz
2023-06-03T18:25:37Z
0 likes, 0 repeats
@galdor (defun foldl (f init seq) (reduce f seq :initial-value init))Fold is just reduce with a mandatory init.Reduce is just a fold where the init is optional and, if not provided, is determined by calling f without arguments.Note: f is never called with just one argument. For example, you can never tickle the arguments to get the unary behaviour from - or /.
(DIR) Post #AWK5eBInA3GbvT9RKK by Ardubal@mastodon.xyz
2023-06-03T18:47:27Z
0 likes, 0 repeats
@louis @galdor I am now a full time Clojure developer for 7 years, and LOOP is definitely still one of the things I occasionally miss.It's just not explicitly functional. If you don't use destructive operations (I think these will generally involve do clauses), you can see it as a declarative way to build up a possibly quite complicated reduce operation.And it is one of the tools with which CL can be very performant.And remember, TCO is not guaranteed in CL (e. g. ABCL can't, since JVM).