Programowanie funkcyjne

0

Hej

Zobaczyłem w kodzie taką o to konstrukcję, oczywiście na potrzeby posta na forum ją uprościłem. Czy spotkaliście się z takim podejściem i jakie to ma zastosowanie, jakiego typu problemy to rozwiązuje?

const outer = () => {
    const inner0 = () => {
        console.log('inner0')
    }
    const inner1 = () => {
        console.log('inner1')
    }
    return {
        inner0,
        inner1
    }
}

Użycie:

outer().inner1()

Osobiście wygląda mi to na robienie z js javy, ale pewnie się mylę i jest to jakiś typowy przykład programowania funkcyjnego.

1

Akurat podany przykład sam w sobie nie ma większego zastosowania, natomiast samo programowanie funkcjne jest, cóż - jestem wielkim fanem ;-)

let foo = [1, 2, 3];

console.log(
  foo.map((x) => x * 2)
);

// ----- //

function fetchSomething() {
  return new Promise((resolve) => {
    resolve(123);
  });
}

function printSomething(sth) {
  alert(sth);
}

fetchSomething().then(printSomething);

I tak dalej, i tak dalej - oczywiście są to przypadki dosyć akademickie, natomiast w rzeczywistym, produkcyjnym kodzie również staram się w miarę możliwości (oraz tam, gdzie jest to czytelne) wykorzystywać programowanie funkcyjne.

jakiego typu problemy to rozwiązuje?

Przede wszystkim czytelnościowe - spróbuj sobie przepisać pierwszy przykład z map na pętlę i porównaj ilość kodu, czytelność, intencje autora itd.
Oczywiście można też próbować zrobić z funkcji młotek na wszystko i wtedy wychodzi jeszcze gorzej, ale cóż :-P

0

Jak na razie to pokazujecie użycie funkcji wyższych rzędów, a nie programowanie funkcyjne.

0
Patryk27 napisał(a):

Akurat podany przykład sam w sobie nie ma większego zastosowania

Cieszę się, że podałeś przykład zastosowania programowania funkcyjnego w js, na pewno przyda mi się w przyszłości, nie mniej jednak pytam o podany konkretny przykład.

1
const outer = () => {
    const inner0 = () => {
        console.log('inner0')
    }
    const inner1 = () => {
        console.log('inner1')
    }
    return {
        inner0,
        inner1
    }
}

Poza używaniem funkcji niewiele ma to wspólnego z programowaniem funkcyjnym - jest to zwykła factory function, służąca do tworzenia obiektów (alternatywa dla klas i prototypów), np:

const user = (name, age) => {
  const describe = () => {
    return `${name}, ${age} years old`
  }

  const getName = () => {
    return name
  }
  
  return {
    describe,
    getName,
  }
}

const me = user('Maciek', 29)

console.log(me.describe()) // -> "Maciek, 29 years old"

tyle, że zapisana z użyciem arrow fuctions zamiast tradycyjnie.

0

Czy takie faktorki są często spotykane w kodzie czy raczej przyjęło się używać klas?

2

Nie wiem czy często, ja zwykle stosuję (choć w trochę innej wariacji), mają kilka zalet:

  • są bardzo proste,
  • obiekty przez nie stworzone mają płaską strukturę (nie ma łańcucha prototypów, czyli nie da się napsuć modyfikując prototyp w runtime),
  • dzięki domknięciu masz pola prawdziwie prywatne (nie żadne sztuczki z Symbolami czy WeakMapami),
  • kompozycja jest bardzo wygodna i naturalna,
  • możesz łatwo zamrozić obiekt,
  • nie musisz używać new (znowu - łatwiejsza kompozycja),
  • możesz się całkowicie pozbyć this i problemów z nim związanych

Minusy:

  • zużywają więcej pamięci niż prototypy/klasy (kopie metod) - tyle, że rzadko jest to wąskie gardło w aplikacji.

Ja używam w tym stylu:

const user = spec => {
  const { name, age } = spec
  
  const describe = () => {
    return `${name}, ${age} years old`
  }
 
  const getName = () => {
    return name
  }
 
  return Object.freeze({
    describe,
    getName,
  })
}

const me = user({ name: 'Maciek', age: 29 })
 
console.log(me.describe()) // -> "Maciek, 29 years old"

1 użytkowników online, w tym zalogowanych: 0, gości: 1