Argüman almayan ve hiçbir şey döndürmeyen bir işlevin adı nedir? [kapalı]


80

Java 8'in java.util.functionpaketinde şunlar var:

  • İşlev : Bir argüman alır, bir sonuç üretir.
  • Tüketici : Bir argüman alır, hiçbir şey üretmez.
  • Tedarikçi : Tartışmaz, bir sonuç üretir.
  • ... : İlkelleri, 2 argümanı vb. İşleyen diğer durumlar ...

Ancak " tartışma yapmaz, hiçbir şey üretmez " vakasını ele almam gerekiyor .

Bunun için hiçbir şey yok java.util.functionnal.

Yani, soru şudur:

' Tartışmasız ve hiçbir şey döndürmeyen bir fonksiyonun ' adı nedir ?

Java 8'de tanımı şöyle olacaktır:

@FunctionalInterface
public interface InsertANameHere {
    void execute();
}

Yürütücü zaten var ve başka bir amacı var: " Gönderilen çalıştırılabilir görevleri yürüten bir nesne ". İmza eşleşmiyor ( execute(Runnable):void) ve işlevsel bir arayüz bile değil .

Çalıştırılabilir var, ancak iş parçacığı bağlamı ile güçlü bir şekilde bağlantılı:

  • Paket java.langdeğil java.util.function.
  • Javadoc şunları belirtiyor: " Çalıştırılabilir arayüz, örnekleri bir iş parçacığı tarafından yürütülmesi amaçlanan herhangi bir sınıf tarafından uygulanmalıdır ".
  • "Runnable" adı, bir iş parçacığı içinde bazı kod çalıştırıyor.

28
"Ama hiçbir şey yok" Tartışmaz, hiçbir şey üretmez. "" - Runnable ?
user11153

11
Bence javadoc Runnablebu noktada modası geçmiş, çünkü bir Runnable Thread( Executorörneğin) dışındaki diğer sınıflar tarafından da kullanılıyor .
SpaceTrucker

13
@superbob Bu Runnablesadece s .run()tarafından olabileceği anlamına gelmez Thread. Aslında, soruda açıklanan amaç için çok yaygın olarak kullanılırlar
blgt

5
@superbob Bu başlangıç ​​amacıydı, ancak Java 8'den bu yana işlevsel arayüz olarak "güçlendirildi". Demek bu yüzden java.util.function pakette hiçbir şey bulamadın .
user11153,

5
Semi-Snark: ImpureFuntion, kesinlikle yalnızca yan etkilere dayandığından, aksi halde çalışmaz. ( en.wikipedia.org/wiki/Pure_function#Impure_functions ) Daha çok Seriosuly: En azından void exec'in ( ) semantiğine uyan emperyal (bir şeyler yap);
Kristian H

Yanıtlar:


71

Java'nın seçimini, her etkinlik için ayrı bir adla yapmak bu kadar aptalcaydı. Tam olarak taklit etmeye değmez. Eğer Ancak, gereken tutarlılık uğruna, ya da çok genel kütüphane kod yazıyorsanız, Konrad'ın önerileri iyi. Yüzüğe atabilirim Procedure.

Sözde işlevsel bir paradigma kullanmak, normal adlandırma ilkelerinin pencereden çıkması gerektiği anlamına gelmez. Arayüzler hemen her zaman onlar sonra ne adlı olmalıdır yapmak değil bazı genel sözdizimsel fikri sonra. İşlevler bir geri alma yığına yerleştirilirse, adlandırılmaları gerekir UndoFunction. GUI olaylarından çağrılırlarsa, adlandırılmaları gerekir GUIEventHandler. Arkadaşlar, arkadaşlarının kötü adlandırma kurallarını sürdürmesine izin vermez.


Procedurede iyi. Bu bağlamda, bu tür bir "yapı" ile ilgilenmesi gereken genel bir kütüphane geliştiriyorum.
superbob

18
ProcedurePascal günlerimden hoşlanıyorum . A'nın Procedureyan etkileri vardır, a Functiondeğildir. Bir değer döndürmediğiniz için yapabileceği tek şey bir yan etkiye sahip olmaktır.
Spencer Rathbun

Kullandığım meyilli olabilir ProcedureRIR<T1,T2>için void proc(T1, int, T2)diğer türleri için aynı şekilde ve - muhtemelen oldukça türlerinin olası her kombinasyon halinde tıkmak çalışırken daha talep üzerine çoğu yaratır.
supercat

1
Gerçekten de, gerçek fonksiyonel programlama genellikle Macarca stil adlandırmasını desteklememektedir. Bu, işlevsellikten ziyade oo paradigmasının zihniyetidir.
Slebetman

3
If the functions are placed into an undo stack, they should be named UndoFunction.Fonksiyonu adlandırmakla farklı bir tür vermek arasında bir fark var. İşlevsel bir tarzda bir yaratmaz UndoFunctonşimdi bunu hiç geçemez çünkü türü flip, curry, compose, filter, mapBence vb farklı arities ile farklı adlar fonksiyonlarını vermek Java'nın kararı aptalca gerçek nedeni budur. Elbette, eğer yan etkileri kullanacaksanız, onu arayın; kompozisyonu pencereden daha önce fırlattınız ve tartışmasız da işlevleri kullanmıyorsunuz.
Doval,

33

Java dünyasında buna denir Runnable. C # dünyasında buna denir Action.

Ancak, daha büyük şeyler için güzel bir şekilde uyan daha iyi bir isim var.

Olayların daha büyük bir görünümü daha sonra gelir, parametresiz geçersiz işlevsel arabiriminizin yanı sıra bir, iki veya daha fazla argüman kabul eden veya bir değer veren benzer işlevsel arabirimlere sahip olmanız gerektiğine karar verdiğinizde. Bu olduğu zaman, bütün bu varlıkların adlarının izomorfik ve birbirleriyle uyumlu olmasını isteyeceksiniz.

Dolayısıyla, Java'da, kendim adı verilen Procedureve şöyle tanımladığım kendi işlevsel arabirimlerim var :

public interface Procedure
{
    void invoke();
}

public interface Procedure1<T1>
{
    void invoke( T1 argument1 );
}

... (resmi aldın.)

Ayrıca, Functions olarak adlandırılan benzer bir arabirim kümesine sahibim , benzer şekilde tanımlanmış, ilk genel parametre dönüş türü:

public interface Function<R>
{
    R invoke();
}

public interface Function1<R,T1>
{
    R invoke( T1 argument1 );
}

Bu yüzden, buradaki amacım bu Procedureçok iyi bir isim çünkü daha güzel şeyler hakkında daha iyi uyuyor. Daha sonra, argümanları kabul eden veya bir değer döndüren yöntemlerle benzer işlevsel arayüzlere sahip olmaya karar verirseniz, buna girersiniz.

NOT: Ben temelolarak Karl Bielefeldt'in “normal adlandırma ilkelerinin pencereden çıkmaması gerektiğini” ve “Arayüzler, genel bir sözdizimsel fikirden sonra değil, yaptıklarından sonra hemen hemen her zaman adlandırılması gerektiğini” iddiasına katılıyorum . Ama o bile "neredeyse her zaman" için izin veriyor. Bazen (aslında isimsiz) prosedürlere ve fonksiyonlara ihtiyaç duyulur ve OP'nin sorduğu şey budur ve ben de cevap veriyorum.

Değişiklik 2017-11-10:

Neden Function1<R,T1>yerine Function1<T1,R>? Her iki şekilde de gidebilir, ancak soldaki dönüş değerleri için bir tercihim var çünkü 'dönüşme' (hedef-kaynaktan) adlandırma kuralını 'dönüşme' (kaynak-adres) yerine izlemeyi severim -destinasyon) kongre. (Bu, bir sözleşmeden daha fazla bir kazadır, gerçekten, hiç kimse, muhtemelen hiç kimseye bir düşünce vermedi, çünkü herhangi bir düşünce vermiş olsalardı, “dönüştür” kongresine ulaşmış olacaklardı. )

Ben bu konuda okumak Joel Spolksy - Yanlış Kod Yanlış Bak yapma , bu, ben bütünüyle okumanızı tavsiye çok uzun makale, ama, elimizdeki dava düz 'TypeFromType', bunlarla arayışını atlamak istiyorsanız size TL'yi verir; DR, fikir bundan myint = intFromStr( mystr )daha iyidir myint = strToInt( mystr ), çünkü ilk durumda türlerin adları ilişkili değerlere yakındır, böylece 'int'nin' int 'ile eşleştiğini kolayca görebilirsiniz. 'str' 'str' ile eşleşir.

Bu yüzden, uzantı olarak, işleri kodda görünecek şekilde sipariş etme eğilimindeyim.


1
Bu çözüm gerçekten iyi, java'nın kendi Tedarikçisi, Tüketici, BiFunction'dan bile daha fazla kurşun geçirmez görünüyor, çünkü her şeyi yalnızca iki konsepte ayırıyor. Bana @Karl Bielefeldt'den “ Java'nın, her aptallık için ayrı bir isimle bu seçimi yapması aptalca olduğu ” hakkındaki cevabını hatırlatıyor . Tek dezavantajı, ilkel türleri ve bunların kombinasyonlarını (DoubleToLongFunction, ToLongBiFunction, ... gibi eğlenceli şeyler) işlememesidir. Ama ilkellerin bir başka endişe ...
superbob

Evet. Temel olarak, jenerik ilaçları ilkellerle değiştirmeye başladığınızda, bu gerçekten performansı önemsemediğiniz anlamına gelir, bu nedenle burada sunulan sözleşmeden sapmanız ve çok özel bir performans iyileştirmesi için çok özel isimler kullanmanız sorun değil.
Mike Nakis

1
2. cevabı kabul edebilseydim, Prosedür N , İşlev N önerileri sayesinde seninkini seçerdim . Hala onu oyladım.
superbob

Neden değil Function1<T1, R>?
ErikE

@ErikE bu çok iyi bir soru ve ben de cevap yazmam için değişiklik yaptım.
Mike Nakis

18

Neden olmasın Command? Veri gerektirmediği ve veri döndürmediği göz önüne alındığında, ancak bunun çağrılmasının bir etkiye neden olduğunu varsayarsak (aksi takdirde gerçekten anlamsız olurdu), kabaca yapabileceği tek şeyin bu olduğunu düşünün - bir eylemi başlatmak, bir şeyler yapmak.

Bundan bahsetmek Actiongerekirse, .NET'te de genel bir delege var. Java'nın aksine Consumer0 ila 16 argüman alabilir; başka bir deyişle, bunun En basit versiyonu hiçbir yük - bkz MSDN'yi .

Ve ad, “tüketmek” için bir şey olmadığı anlamına gelmediğinden, iyi bir isim seçimi gibi görünüyor.


1
Commandiyidir. Komut düzeni ile karıştırılabilir, ancak çözüm olabilir.
superbob

7
Ben Actiondaha fazlasını seviyorum Command. Bir komut, yan etkileri için bir eylem yürütülürken, alınan ve değerlendirilen bir şeye benzer.
Bergi

7
Umm ... nasıl bir Komut kalıbı olamaz ? Tam olarak Komuta varlıklarını yaptınız! Hatta geleneksel olarak adlandırılmış bir execute()metoda sahiptir. 0_o '
türban

1
Eylem önerisinden hoşlanmamak, ortak (ve iyi) bir Swing arayüzü. Komut makul.
user949300,

@ user949300 ancak içeriğe bağlı - Java, gördüğünüz büyük bir dünya, Android geliştiricisiyim (şimdi) ve J2EE ile ilgili hiçbir özelliğe sahip değilim;) Elbette, seçilen adlandırma kuralının çakışmaması gerektiğini kabul ediyorum. senin çerçevenin kullandığı ile.
Konrad Morawski
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.