Remix.run Logo
kazinator 2 days ago

You also have to go through gymnastics of syntax to write a shell program that anyone could reliably use on any data, with any file names.

  $ txr
  This is the TXR Lisp interactive listener of TXR 299.
  Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
  Poke a few holes in TXR with a fork before heating in the microwave.
  1> (flow (glob "/proc/*") (take 10))
  ("/proc/1" "/proc/10" "/proc/101" "/proc/102" "/proc/103" "/proc/104"
   "/proc/107" "/proc/1074" "/proc/1086" "/proc/11")
  2> (flow (glob "/proc/*") (take 10) (map (op trim-left "/proc/")))
  ("1" "10" "101" "102" "103" "104" "107" "1074" "1086" "11")
  3> (flow (glob "/proc/*") (take 10) (map (op trim-left "/proc/")) (sort @1 : toint))
  ("1" "10" "11" "101" "102" "103" "104" "107" "1074" "1086")
  4> (flow (glob "/proc/*") (take 10) (map (op trim-left "/proc/")) (sort @1 greater toint))
  ("1086" "1074" "107" "104" "103" "102" "101" "11" "10" "1")
How about we parse digit sequences out of the path names and combine them with the originals, then sort on those digit sequences turned into integers:

  5> (defun get-nums (str)
       (flow str (tok #/\d+/) (map toint)))
  get-nums
  6> (flow (glob "/proc/*") (take 20) (csort @1 greater get-nums))
  ("/proc/11170" "/proc/11169" "/proc/1222" "/proc/1199" "/proc/1198"
   "/proc/1194" "/proc/1133" "/proc/1104" "/proc/1086" "/proc/1074"
   "/proc/117" "/proc/107" "/proc/104" "/proc/103" "/proc/102" "/proc/101"
   "/proc/12" "/proc/11" "/proc/10" "/proc/1")
csort is caching sort: it caches the result of the key function through which the elements are projected to form the argument of the comparison. In other words, so we don't wastefully call get-nums multiple times for the same path.