Sto scrivendo sulla sintassi del linguaggio. Esiste un linguaggio là fuori in cui i parametri sono inseriti all'interno del nome del metodo?

29

in JavaScript:

function getTopCustomersOfTheYear(howManyCustomers, whichYear) {
   // Some code here.
}
getTopCustomersOfTheYear(50, 2010);

in C #:

public List<Customer> GetTopCustomersOfTheYear(int howManyCustomers, 
 int whichYear)
{
   // Some code here
}
List<Customer> customers = GetTopCustomersOfTheYear(50, 2010);

in PHP:

public function getTopCustomersOfTheYear($howManyCustomers, $whichYear)
{
   // Some code here
}
$customers = getTopCustomersOfTheYear(50, 2010);

C'è qualche linguaggio là fuori che supporta questa sintassi:

function GetTop(x)CustomersOfTheYear(y)
{
    // Some code here
}
returnValue = GetTop(50)CustomersOfTheYear(2010);

Non è più una forma semantica e più leggibile di scrivere una funzione?

Aggiornamento: Il motivo per cui sto facendo questa domanda è che sto scrivendo un articolo su una nuova sintassi per una nuova lingua. Tuttavia, pensavo che avere questa sintassi per dichiarare i metodi potesse essere più gradevole e più amichevole per gli sviluppatori e diminuirebbe la curva di apprendimento della lingua, perché sarei più vicino al linguaggio naturale. Volevo solo sapere se questa funzione è già stata contemplata o meno.

    
posta Saeed Neamati 10.03.2016 - 22:05
fonte

16 risposte

41

Sì, e sì. Sì, c'è un tale linguaggio e sì, molte persone lo trovano più leggibile una volta che ci si abitua.

In Objective-C, il metodo sarebbe:

- (NSArray*)getTop:(int)count customersOfTheYear:(Year)year;

In realtà è un esempio abbastanza forzato che non legge molto bene, quindi eccone uno migliore dal codice attuale:

+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;

Che il prototipo di un metodo che restituisce una nuova istanza UIColor utilizzando i valori rosso, verde, blu e alfa. Lo chiameresti in questo modo:

UIColor *violet = [UIColor colorWithRed:0.8 green:0.0 blue:0.7 alpha:1.0];

Ulteriori informazioni sui nomi dei messaggi con i parametri interspati in Il linguaggio di programmazione Objective-C .

    
risposta data 24.08.2011 - 21:44
fonte
25

Risposta: smalltalk

link

'hello world' indexOf: $o startingAt: 6 è come%% di j_ca% di Java

"hello world".indexOfStartingAt(o, 6) è come%% di j_ca% di Java

La sintassi è ... Rectangle width: 100 height: 200 Il nome del metodo chiamato è la concatenazione di tutte le parole.

    
risposta data 23.08.2011 - 02:04
fonte
17

Credo che tu stia cercando l'astrazione chiamata " interfaccia fluente (sono qui presente sollevando un commento, originariamente creato da @Jesper, a una "risposta"). " Questo modello ora comune è stato implementato con successo in molte lingue, di cui l'Objective-C è solo uno.

Ecco un esempio abbastanza pulito:

Person bo = new Person();
bo.Set.FirstName("Bo").LastName("Peep").Age(16).Size("Little").LostHerSheep();

Puoi vedere come qualcosa del genere può essere implementato in Randy Patterson 's Come progettare un'interfaccia fluente .

Andre Vianna fornisce una breve cronologia e discute le possibili implementazioni in altre due parti dell'articolo, incluse molte informazioni utili . Vianna rimanda alla vecchia idea che ho incontrato per la prima volta in Smalltalk 80 chiamato "cascading , "che abilita l'invio di più messaggi allo stesso oggetto. Sembrava questo:

aThing one: 'one';
  two: 'two';
  other.

In seguito il collegamento a cascata si è evoluto in " concatenamento dei metodi ", dove " Fai in modo che i metodi di modifica restituiscano l'oggetto host, in modo che più modificatori possano essere richiamati in una singola espressione. " Il metodo di concatenamento in seguito è cresciuto fino a diventare fluente interfaccia concetto che conosciamo e usiamo spesso oggi. Quello che pensi di fare sembra molto simile.

Ayende Rahien spiega come " fluent interface "potrebbe differire in modo significativo da" method chaining "per meritare il proprio nome .

Le interfacce fluenti sono comunemente presenti in alcuni dei nuovi strumenti utilizzati in sviluppo guidato dal comportamento (BDD) e hanno persino trovato si dirigono verso NUnit , uno strumento di test delle unità .NET più importante, nella sua nuova Modello di asserzione basato su vincoli .

Questi approcci di base sono stati successivamente implementati in altre lingue, tra cui Ruby, Python, C #, Objective-C e Java . Per implementare qualcosa di simile, vorrai studiare l'idea di " chiusura ", che è carina molto fondamentale per concatenare e scioltezza.

Forse puoi migliorare su questi modelli; è così che otteniamo grandi nuovi linguaggi. Tuttavia, credo che la piena comprensione del metodo concatenato e delle interfacce fluenti ti darà un ottimo punto di partenza dal quale far evolvere le tue idee!

    
risposta data 06.09.2011 - 18:03
fonte
16

L'obiettivo-C lo fa. Ecco un tipico prototipo:

- (void) areaWithHeight: (float) height andWidth: (float) width;

Ecco come si chiama un tale metodo:

float area = [self areaWithHeight: 75 andWidth: 20];

Objective-C viene utilizzato principalmente con Cocoa per Mac OS X e Cocoa Touch per iOS, ma gcc costruirà il codice Objective-C su quasi tutte le piattaforme su cui gcc funziona.

    
risposta data 22.08.2011 - 20:19
fonte
13

In Common lisp, puoi definire argomenti per parole chiave per una funzione come questa:

(defun area (&key width height)
    (* width height))

La funzione è chiamata così:

(area :width 2 :height 3)

In Ada non hai bisogno di una dichiarazione speciale - puoi chiamare qualsiasi procedura o funzione alternativamente elencando gli argomenti in ordine, o nominando gli argomenti in questo modo:

a := area(width => 2, height => 3);

Infine, la libreria boost include uno strato di hack per aggiungere la funzione a C ++: link

    
risposta data 12.12.2015 - 16:30
fonte
5

Non sono riuscito a trovarne il nome, ma esiste un modello di progettazione per realizzare qualcosa di simile, in cui una chiamata di funzione restituisce un nuovo oggetto modificato come descritto. Ad esempio:

query = db.getTopCustomers(50).forYear(2010);

Non è usato molto spesso perché i tuoi dati devono essere molto ortogonali al fine di evitare complessità ingestibile sotto il cofano, ma possono essere utili nelle giuste circostanze.

    
risposta data 22.08.2011 - 20:13
fonte
5

Python ha parametri di parole chiave. Esempio di definizione della funzione

def getTopCustomers(count,year):
...

Esempio di chiamata di funzione

x = getTopCustomers(year=1990, count=50)

(Capisco che questo non sia proprio nello spirito della domanda originale, ma se i parametri delle parole chiave in lisp si qualificano, lo fanno anche in questo caso. In Smalltalk e Objective-C, tuttavia, le parole chiave tra gli argomenti fanno davvero parte della funzione nome / ricerca).

    
risposta data 23.08.2011 - 04:32
fonte
4

Agda ha notazione mixfix

if_then_else x y z = case x of
                     True -> y
                     False -> z

 if cond then x else y

Ogni volta che la funzione viene chiamata con un carattere di sottolineatura, può essere divisa in due parti con un argomento tra

    
risposta data 06.10.2013 - 04:31
fonte
4

Pur non essendo un linguaggio di programmazione per sé , Cucumber prende i parametri nel mezzo di nomi di funzioni, che possono includere spazi e sono pensati per sembrare inglese.

Le "funzioni" sono definite in Ruby tuttavia

# definition
Given /^I calculate (.*) times (.*)$/ do |x, y|
    @result = x.to_i * y.to_i
end

Then /^the result should be (.*)$/ do |v|
    @result.should == v.to_i
end

# usage
Scenario:
    Given I calculate 6 times 9
    Then the result should be 42
    
risposta data 12.12.2015 - 16:24
fonte
4

In TeX è possibile definire macro con un "pattern di argomenti" che in pratica significa che il protocollo di chiamata è libero. Per il tuo esempio specifico, puoi usare

\def\getTopCustomers#1OfTheYear#2;{%
  The #1 top customers of the year #2.
}
\getTopCustomers 50 OfTheYear 2010;

Nota che è anche possibile sbarazzarsi di ; se si accetta di giocare con i registri:

\newcount\customers
\newcount\year
\def\getTopCustomers#1OfTheYear{%
  \customers#1\relax
  \afterassignment\reallyGetTopCustomersOfTheYear
  \year
}
\def\reallyGetTopCustomersOfTheYear{%
  The {\the\customers} top customers of the year {\the\year}.
}
\getTopCustomers 50 OfTheYear 2010

TeX ti permette di riconfigurare il suo lexer, e grazie alla macro \afterassignment che ho usato sopra, puoi usare le procedure built-in per i numeri lex. È molto utile definire i protocolli di chiamata molto concisi . Ad esempio, è molto plausibile scrivere macro TeX che comprendano la notazione Markdown per le tabelle.

Ora chiedi "come posso accedere al mio database in cui i clienti sono archiviati da TeX?", ma questa è un'altra domanda. :)

In Common lisp, è sicuramente possibile definire una macro query che ti permetta di scrivere

(query getTopCustomers 50 OfTheYear 2010)

dove getCustomers e OfTheYear sono interpretati come simboli. È quindi compito della macro dargli un senso. Common lisp è eccellente nel dominio della leggibilità del codice (sì, intendo!) Perché il sistema macro consente di creare facilmente pseudo-lingue ottimizzate per la vostra applicazione. (Penso che siano chiamate lingue dell'applicazione.)

P.S .: Sembra che nessuno abbia citato C ++. Il più vicino che puoi ottenere (senza il preprocessore) è

query.getTopCustomers(50).OfTheYear(2010):

il trucco è lasciare che getTopCustomers restituisca un riferimento su query (o qualsiasi altra cosa) che implementa anche OfTheYear . È possibile creare questo esempio fino a un linguaggio di query di piccole dimensioni, ma è necessario identificare le proprietà finali (restituendo un valore) o aggiungere un metodo finalise (eseguendo la ricerca e restituendo il valore). Se ne hai voglia, puoi anche imitare i controller di streaming di STL e poter scrivere cose come

query << getTopCustomers(50) << OfTheYear(2010) << flush;

ma questo va di nuovo nella direzione dei linguaggi delle applicazioni.

Modifica: ho trascurato le risposte @han, che citano anche Common Lisp e C ++ (ma non TeX!).

    
risposta data 12.12.2015 - 16:26
fonte
2

In JavaScript o in qualsiasi altra lingua che supporti le chiusure, puoi curry una funzione come questa:

function getTopCustomersFunc(count) {
    return function(year) {
       // run some query, return count customers from year
    }
}
var top20Func = getTopCustomersFunc(20);
var top20Customers2005 = top20Func(2005);
var top20Customers2008 = top20Func(2008);
    
risposta data 12.12.2015 - 16:24
fonte
1

Dipende dalla tua definizione di "lingua", ma il framework di testing su robot ti consente di definire le parole chiave in questo modo. Dalla loro documentazione su argomenti incorporati :

Select ${animal} from list | Open page | pet selection
                            | Select item from list | animal_list | ${amimal}

Quanto sopra dichiara una nuova parola chiave (essenzialmente una funzione) chiamata "select $ {animal} dalla lista" dove '$ {animal}' è un parametro. Lo chiami come "seleziona gatto dalla lista"

    
risposta data 24.08.2011 - 22:53
fonte
1

Inform 7.

To create (employee - a person) being paid (salary - a number):
    say "Welcome to your new job, [name of employee]!";
    choose a blank row from the table of employees;
    now the paid entry is the salary;
    now the name entry is the name of the employee.

E così via.

    
risposta data 16.02.2013 - 22:41
fonte
0

Le parole chiave di Common Lisp sono già state citate, ma i macro di Common Lisp lo consentono anche abbastanza facilmente:

(defmacro get-my-element (from list at index)
  '(nth ,index ,list))

Questo può quindi essere chiamato così:

(get-my-element from '(a b c) at 1) ;returns B

Una cosa da notare, però, è che i termini from e at non sono applicati. Ci deve essere qualcosa lì, saltarli completamente è un errore, ma dal momento che la macro finisce per scartarli, non importa molto quello che sono oltre la leggibilità (che è importante):

(get-my-element from '(a b c) 3 1) ;also returns B
    
risposta data 05.10.2016 - 16:53
fonte
-2

In Clojure, è comune usare gli argomenti delle parole chiave per situazioni come questa, ad esempio:

(get-customers :top 50 :year 2010)

Gli argomenti delle parole chiave sono abbastanza flessibili, possono essere facoltativi e specificare i valori predefiniti ecc.

    
risposta data 06.10.2013 - 02:05
fonte
-4

Puoi emulare questo in python. Ad esempio,

def GetTop(customers, ofYear):
  #write some code here to get the customers

print GetTop(customers=50 ofYear=2010)

o anche

def GetTop(**args):
  #write some code here using the same parameter names as above

print GetTop({customers: 50, ofYear: 2010})
    
risposta data 12.12.2015 - 16:25
fonte

Leggi altre domande sui tag