Hacker News new | ask | show | jobs
by kazinator 18 days ago

  1> (mapdo (op put-line `@1: @2`) '#"how now brown cow" 0)
  how: 0
  now: 1
  brown: 2
  cow: 3
  nil
mapdo: a mapping function for side effects of calling the function, not calculating a result, like map does.

op: produce a lambda expression out of an expression in which @1, @2, ... explicitly indicate the insertion of positional arguments, which are implicitly collected and become the parameter list of the lambda.

`...`: quasistring syntax: supports @ notations for interpolating. The @1, @2 elements of op do not require a double @@ inside a quasistring.

put-line: ordinary function to put a string to a stream (standard output by default) followed by newline. The lambda generated by op contains a (put-line ...) expression as its body, with @1 and @2 transformed into references to to generated, unique parameter names.

#"...": string list literal: contents are broken on whitespace and denote a list of strings #"foo bar" -> ("foo" "bar"). Requires ' quote in front to be quoted literally, and not evaluated as a compound expression applying the argument "bar" to the operator "foo". Yes, there is a #`...` quasi string list for templating over this.

nil: the value returned by mapdo after the side effects, printed by the REPL, not part of the output.

0: ordinary integer zero. But endowed with the power of being iterable. Where an iterable thing is required, 0 denotes the whole numbers 0, 1, 2, ... Similarly, 42 denotes 42, 43, ...

These are some of the ingredients produced by my one-member research programme into nicer Lisp coding.

  2> (map (ret `@1: @2`) '#"how now brown cow" 0)
  ("how: 0" "now: 1" "brown: 2" "cow: 3")
map: take tuples by iterating over argument iterables in parallel, pass them to a function to project each tuple to a value, then return a list of values.

ret: cousin of op built on the same framework as op. Used for turning an expression into a lambda, when the expression isn't a compound form with an obvious operator. To turn (foo bar) into a lamdbda with op we use (op foo bar). But what if we have a simple variable x and want (lambda () x)? (op x) is not right, it means (lambda () (x)). (ret x) provides the sugar. Here, it lets us spin up a two-argument function that evaluates a quasistring.