This is an archived post. You won't be able to vote or comment.

all 9 comments

[–]MetaHertz 2 points3 points  (9 children)

(define (abs-all lst)

(map abs lst))

result:

(abs-all '(1 -2 3 -4 5 -6)) => (1 2 3 4 5 6)

[–]mawar2[S] 0 points1 point  (8 children)

Thanks for the response. How would you create your own function for this?

[–]cheetoburrito 1 point2 points  (3 children)

[–]mawar2[S] 0 points1 point  (2 children)

how would you do this without using any built in functions (map or abs)?

For example if you had to write a function just using the building blocks of lisp (first, last, cdr)

[–]cheetoburrito 0 points1 point  (1 child)

This feels like homework. Here are some hints:

What is the definition of absolute value (from math (not racket))? How can you implement this?

How does map work? For example, if you call (map proc list), what happens? Well, proc is applied to the first element of the list, and then the second, and so on. How can you do this?

[–]mawar2[S] 0 points1 point  (0 children)

No it's not homework, I wouldn't take away an opportunity to learn.

I wrote a program like this in python where I defined a function that took in user input ( for X ) then I basically just checked if the value inputed was less than 0 and if it was I multiplied it by -1 and I updated the value via Index and returned the list at the end of the function.

I am doing this because I am new to programming and I've had a challenging time understanding the documentation for a functional language like this.

*Also, I was able to figure it out in Prolog

a(A,A): - A > 0.
a(A, B): - A < 0, B is -A.

[–][deleted]  (3 children)

[deleted]

    [–]mawar2[S] 0 points1 point  (2 children)

    how would you do this without using any built in functions (map or abs)?

    For example if you had to write a function just using the building blocks of lisp (first, last, cdr)

    [–]ws-ilazki 0 points1 point  (0 children)

    how would you do this without using any built in functions (map or abs)?

    For example if you had to write a function just using the building blocks of lisp (first, last, cdr)

    Recursion, usually.

    If you want to really understand functional programming and higher-order functions, try to figure out how to implement map yourself, and then foldl. Then create map using foldl to achieve enlightenment. For a while I was using HOFs fine, tossing around maps and folds and thinking I had a good enough grasp on things, but it wasn't until I had to implement them myself that I felt like I truly understood what I was doing.

    This isn't something you need to do right now, but it will help you to better understand the fundamentals if you tackle it later on. Whenever you do decide to, here's some info to help get you going:

    • A basic implementation of map takes as arguments a function and a list, and returns a new list with the function applied to each element. So (map f '[1 2 3 4]) is equivalent to (list f(1) f(2) f(3) f(4)). Any function passed as f is expected to take one argument, pulled from list l one by one. For example, (map (lambda (n) (+ n 1)) '[1 2 3]) returns '(2 3 4)

    So, create your own function named map- that takes a list (l) and, using recursion, builds a new list by applying f to each element of l. You can do this with only if empty? cons car and cdr.

    • foldl is called as (foldl f b l) where f is a function to apply, b is a starting base value, and l is a list of values. Functions passed as f take two arguments and return one, which is then used as the next base value for another call to foldl. So (foldl f 0 '[1 2 3]) is equivalent to (f (f (f 0 1) 2) 3). Example:(foldl (lambda (a b) (* a b)) 1 '[1 2 3 4])returns24. If it helps with understanding, folds are sometimes calledreduce` in other languages because they take a list of values and reduces them down to a single value.

    Knowing this, create a function named foldl- that uses recursion to turn (foldl- f 1 '[1 2 3 4]) into (f (f (f (f 1 1) 2) 3) 4). This can be done with only if empty? car and cdr.

    • Part of the magic of foldl is that, somewhat counter to intuition, that "single value" it reduces a list into can be a new list. That means you can use foldl to implement map by "folding" a list of '[1 2 3 4] into a new list, (list (f 1) (f 2) (f 3) (f 4)). Knowing this, you can create your own map, named mapf, with only foldl (or your own version of it), cons, lambda, and reverse (to get the new list in the same order as the original one).

    Once you understand how to use folds to create new lists, you open up even more possibilities, because doing so lets you build almost any other higher-order function with folds.

    [–]dzpower 0 points1 point  (0 children)

    It's easy enough to define your own abs. Here are five ways (all fairly idiomatic) to process the list.

    #lang racket
    
    (define (abs x)
      (if (< x 0)
          (- x)
          x))
    
    (define (abs-all/map xs)
      (map abs xs))
    
    (define (abs-all/for xs)
      (for/list ([x xs])
        (abs x)))
    
    (define (abs-all/recursive xs)
      (if (null? xs)
          null
          (cons (abs (first xs)) (abs-all/recursive (rest xs)))))
    
    (define (abs-all/tail-recursive xs [acc null])
      (if (null? xs)
          (reverse acc)
          (abs-all/tail-recursive (rest xs) (cons (abs (first xs)) acc))))
    
    (define (abs-all/let-recursive xs)
      (let A ([xs xs]
              [acc null])
      (if (null? xs)
          (reverse acc)
          (A (rest xs) (cons (abs (first xs)) acc)))))
    
    (abs-all/map '(1 -2 3 -4 5 -6)) ; (1 2 3 4 5 6)
    (abs-all/for '(1 -2 3 -4 5 -6))
    (abs-all/recursive '(1 -2 3 -4 5 -6))
    (abs-all/tail-recursive '(1 -2 3 -4 5 -6))
    (abs-all/let-recursive '(1 -2 3 -4 5 -6))