Bir işlev başka bir işlevden değer alan saf kabul edilir mi?


9

Yan etkileri olmayan işlevler yaparken varsayılan değişken değerleri işlemek için bir yol bulmaya çalışıyorum ve aşağıdaki ile sona erdi:

function getDefaultSeparator() {
    return ':';
}

function process(input, separator) {
    var separator = separator || getDefaultSeparator();

    // Use separator in some logic

    return output;
}

Varsayılan ayırıcı diğer işlevlerde kullanılacaktır ve yalnızca tek bir yerde tanımlamak istiyorum.

Bu saf bir işlevse, bunun yerine yalnızca global bir DEFAULT_SEPARATOR sabiti kullanmanın farkı nedir?


5
Daha sonra eklenecek bir mantık için işlevi yer tutucu olarak kullanmayı düşünmüyorsanız, önemli bir fark yoktur.
Robert Harvey

3
Olası bir kopya, bir işlev parametre olarak bir işlev alıyorsa, hemen bir şekilde saflaşmaz mı? . Soru tam bir kopya değil, ama cevap aynı olmalı. ("Diğer işlevin saflığına bağlıdır.")
jpmc26

1
Global bir sabit kullanmak bir işlevi saflaştırmaz. Eğer küresel bir değerinin kullanılması farz sabit yapmasıdır.
chepner

Btw, curry process(ters parametre sırası ile) ve curried fonksiyonunuvar processDefault = process(":")
bob

Yanıtlar:


22

Bir işlev başka bir işlevden değer alan saf kabul edilir mi?

Bu, diğer işlevin ne yaptığına ve çağrı işlevinin ne yaptığına bağlıdır. Safsızlık bulaşıcıdır, saflık değildir.

Saf bir işlevin çağrılması, çağırma işlevinin saflığını değiştirmez. Bir saf olmayan fonksiyonun çağrılması, çağrı fonksiyonunun da otomatik olmasını sağlar.

Yani, örneğinizde, dışarıda bıraktığınız parçanın saflığına bağlıdır: bu safsa, tüm işlev saftır.

Bu saf bir işlevse, bunun yerine yalnızca global bir DEFAULT_SEPARATOR sabiti kullanmanın farkı nedir?

Hiçbir şey değil. Her zaman aynı değeri döndüren bir işlev, bir sabitten ayırt edilemez. Aslında, λ-hesabı içinde sabitler tam olarak bu şekilde modellenir.


2
"Bir saf olmayan fonksiyonu çağırmak otomatik olarak çağırma işlevini de saflaştırmaz" Bundan emin misiniz? AFAICS, saf olmayan bir işlevi çağırmak, arayanı otomatik olarak saflaştırmaz, ancak bunu yapabilir.
Tekilleştirici

2
@ Duplicalicator: Ne kadar statik analiz yapabileceğinize (rahatsız edilebileceğiniz) bağlıdır. Elbette, func0'ı geçtiğinizde yan etkileri olan bir işlev varsa , ancak 1'i geçtiğinizde değil, o zaman funckendisinin "saf olmayan" olmasına rağmen , işlev olarak adlandırılan bir işlev func(1)(ve dönüş değerini görmezden gelelim) demek) mutlaka saf değildir. Arayan func"lekelenmiş" potansiyel olarak saf olmayan varlık olarak arayan kişiye yeterli, ancak bazı yollarla Kusurlu bir fonksiyon kudreti sonuçta saf olduğu kanıtlanmış. En azından saf / saf olmayan dilin içinde tanımlanmadığı javascript'te.
Steve Jessop

6

Evet, her ikisi de saf işlevlerdir (elip edilen parçanın da saf olduğu varsayılarak):

  1. Sonuç sadece parametrelere bağlıdır.
  2. Hiçbir yan etkisi yoktur.

Not eğer getDefaultSeparator()saf fonksiyon değildi, o zaman ne olurprocess() saf.

Javascript'te, saf fonksiyon veya sabit kullanma arasında anlamlı bir fark yoktur ve Javascript'in fonksiyonları yeniden tanımlama veya sabit değerlerini değiştirme yeteneği önlendiği sürece her ikisi de saf fonksiyon tarafından kullanılabilir.

Saf fonksiyonların arkasındaki anahtar kavram, programın sonuçlarını etkilemeden geri döndükleri değerle değiştirilebiliyor olmalarıdır.


1

Diğerlerinin söylediği gibi, bu hala saf bir işlevdir.

Bununla birlikte, tasarım sorunları hakkında konuşalım. Değeri yalnızca bir kez koyarak DRY kodunu saklamak için bir şeyler yapmaya çalışabilirsiniz. Buna ek olarak, benim de düşünülmesi gereken, uygun olan bağlantı seviyesidir.

Bir işlevi kullanmak, uygulamayı değiştirmek için daha fazla esneklik sağlar; başka bir deyişle, işlev yaklaşımı, genel bir değişkenden daha gevşek bağlantı sunar.

Soru, kişinin buna ihtiyacı olup olmadığıdır.

Tüketiciler ve sağlayıcı aynı modüldeyse ve sağlayıcı modüle özel ise, sağlayıcının özel bir değişkenten bir değişkene yükseltilmesi gerektiğinden, bu gevşek bağlantı düzeyinin gerekli olduğunu iddia etmek zordur. özel yöntem, modül içinde basit bir yeniden düzenleme tüketiciye aynı anda uygulanabilir. Gerçekten ihtiyaç duymadan önce bir yöntem / işlev kullanmak YAGNI altına girebilir.

Tüketici (ler) ve sağlayıcı farklı modüllerde olsa bile, modüller birlikte sürümlendirilmişse (örneğin, tüketici ve sağlayıcı modüllerinin aynı dosyada olması için bir küçültücü kullanırsınız), YAGNI da uygulanabilir.

Öte yandan, örneğin, üretici, tüketiciden ayrı olarak sürümlendirilmiş bir kütüphane ya da API paketinde ya da modülündeyse, işlevi kullanmak uygun olabilir. Bu durumda API'nın uzun ömürlülüğüne ve OCP gibi ilkelere bakmalıyız.

(Başka bir notta, kodunuz önemli boyutlardaysa, modüllerin global değişkenler ve işlevler yerine alanlar ve yöntemler ile kullanılmasını teşvik ederim.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.