• re: Elegant solution asked

    From B. Pym@21:1/5 to All on Sat Sep 7 08:19:39 2024
    XPost: comp.lang.scheme

    Very often I need a function to map a 2 argument function over a list and
    a fixed argument. For example, if we call such function map1:
    (map1 #'list 'z '(a b c)) should return: '((z a) (z b) (z c))

    Can anyone suggest an elegant solution for this. The best I could come up with was:

    (defun map1 (function fixed-argument list)
    (mapcar (lambda (element) (funcall fn fixed-argument element)) list))

    This works fine, but I have the gut feeling that there must be a better/simpler way. Any ideas?
    Thanks in advance.
    Please reply to: [email protected]

    I prefer the following (I guess because it avoids the funcall), although
    I don't claim it is is significantly better.

    (defun map1 (function fixed_argument list) (mapcar function
    (mapcar #'(lambda (x) fixed-argument) list) list))

    Scheme

    (map (curry list '--) '(a b c))
    ===>
    ((-- a) (-- b) (-- c))

    (map (curryr list '--) '(a b c))
    ===>
    ((a --) (b --) (c --))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to Barry Margolin on Sat Aug 30 08:30:57 2025
    Barry Margolin wrote:

    (defun map-with-constant (mapping-function function constant &rest lists)
    (apply mapping-function function (circular-list constant) lists))

    This can then be used as
    (map-with-constant #'mapcar #'cons 1 '(1 2 3)) =>
    ((1 . 1) (1 . 2) (1 . 3)).


    Scheme

    (% map (cons 'X _) '(1 2 3))
    ===>
    ((X . 1) (X . 2) (X . 3))

    Given:


    ;; Anaphoric macro to abbreviate lambdas for higher-order functions.
    ;; Uses "_" for 1 argument;
    ;; uses "A:" and "B:" and so on for 2 or more arguments.
    ;; This version works under both Gauche Scheme
    ;; and Racket. Racket needs:
    ;; (require compatibility/defmacro)
    ;; When used with functions such as "map" and "fold", the macro
    ;; can deduce the number of arguments the lambda will receive.
    ;; The number of arguments can be specified by an integer
    ;; after the function name. For example:
    ;; (% 2 lset-adjoin (eq? B: (char-upcase A:)) '(#\M #\N) #\m #\o)
    ;;
    (define-macro %
    (case-lambda
    ((func expr List) `(,func (lambda(_) ,expr) ,List))
    ((func expr . more)
    ;; Number of arguments received by the lambda.
    (let ((n (if (integer? func)
    (begin0
    func
    (set! func expr)
    (set! expr (car more))
    (set! more (cdr more)))
    (length more))))
    (let* ((nums (do ((i n (- i 1))
    (r '() (cons (+ i 64) r))) ((= 0 i) r)))
    (vnames
    (map (lambda(n)
    (string->symbol (string (integer->char n) #\:)))
    nums)))
    `(,func (lambda ,vnames ,expr) ,@more))))))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)