Nonostante abbia risposto a svariate migliaia di domande nei vari Forum italiani ed americani, questa è la mia prima esperienza da blogger. Spero quindi che vorrete perdonarmi eventuali lacune o manchevolezze, e che mi aiuterete con i vostri suggerimenti.

Prima di iniziare la nostra panoramica su ricorsioni e funzioni personalizzate in FileMaker, vorrei fare un paio di precisazioni. Per parlare delle funzioni, sia native che personalizzate, userò principalmente l'inglese. Un po' per abitudine e un po' perché, copiando ed incollando le funzioni nella versione italiana, FileMaker procederà automaticamente a tradurle. Inoltre, nei miei esempi mi capiterà spesso di citare le funzioni personalizzate presenti sul sito di Brian Dunning, che potete trovare a questo link.

Cos’è una funzione personalizzata

La funzione personalizzata è un calcolo che utilizza le normali funzioni di FileMaker, combinandole in modo tale da raggiungere un risultato particolare. Questo calcolo può essere molto semplice ma anche molto complesso. Spesso, inoltre, è possibile ottenere lo stesso risultato in tantissimi modi, più o meno precisi e più o meno veloci.

Come esempio pratico vi citerò alcune funzioni che fanno tutte la stessa cosa: verificare se un determinato anno è bisestile oppure no.

  1. leapyear ( date ) http://www.briandunning.com/cf/164
  2. LeapYear ( Year ; Tipe ) http://www.briandunning.com/cf/462
  3. LeapYear ( TheYear ) http://www.briandunning.com/cf/527
  4. LeapYear ( date ) http://www.briandunning.com/cf/555
  5. LeapYear(y) http://www.briandunning.com/cf/557
  6. LeapYear ( yourDate ) http://www.briandunning.com/cf/764
  7. isLeapYear ( _year ) http://www.briandunning.com/cf/765

Qualcuno di voi avrà già notato che nessuna di queste funzioni è ricorsiva: in nessuna di esse, cioè, viene richiamata nel calcolo la funzione stessa. Questa non ricorsività delle funzioni consente di utilizzarle anche in semplici campi calcolati. Non è quindi necessario disporre della versione Advanced di FileMaker, l'unica che consente la creazione di una funzione personalizzata, o custom function (CF).

Ciò che ha reso la funzione personalizzata importante, e fino all'avvento dei trigger quantomeno indispensabile, è la possibilità che essa richiami sé stessa così da creare un ciclo simile al loop di uno script. Per la verità ci sono alcune differenze con il loop: prima tra tutte la limitazione delle ricorsioni, che devono essere minori di 10.000 (o di 50.000 per la cosiddetta "ricorsione in coda").

Ricorsione normale

La forma classica della chiamata ricorsiva è, in Italiano:

Finché è vera la condizione, memorizza il risultato del calcolo e ripeti l'operazione con parametri modificati; altrimenti scrivi il risultato ed esci

Vediamo, ad esempio, come invertire le parole di una frase. In Italiano:

Finché il testo contiene delle parole, memorizza la parola a destra della frase e ripeti l'operazione con le parole rimanenti; altrimenti scrivi il risultato ed esci

che in FileMaker diventa:

[sourcecode]

//Reverse ( text ) custom function

If ( WordCount ( text ) ;
Trim ( RightWords ( text ; 1 ) & " " &
Reverse ( LeftWords ( text ; WordCount ( text ) - 1 ) ) ) )

[/sourcecode]

Reverse (oggi è una bella giornata di sole splendente) restituirà:

splendente sole di giornata bella una è oggi

E' improbabile che il testo da dare in pasto a questa funzione contenga più di 10.000 parole ma, in questo caso, la funzione restituirebbe:

? ( punto interrogativo )

FileMaker, Inc. ci dice infatti che esiste un limite di 10.000 ricorsioni che, come già detto in precedenza, può essere superato solo con la ricorsione in coda (tail recursion).

Ricorsione in coda

Finché è vera la condizione, ripeti (senza memorizzare alcunché) l'operazione con parametri modificati; altrimenti scrivi il risultato ed esci

Vediamo ad esempio, come calcolare il Massimo Comun Divisore (MCD) tra due numeri interi positivi A e B con l'algoritmo di Euclide. In Italiano:

Finché B è diverso da 0, ripeti MCD ( B ; resto della divisione tra A e B ) ; altrimenti scrivi A

che in FileMaker diventa:

[sourcecode]
// MCD ( A ; B ) custom function
If ( not B ; A ; MCD ( B ; Mod ( A ; B ) ) )

[/sourcecode]

Con dati reali si ottiene che MCD (70 ; 56) è uguale a 14. Ma quante ricorsioni ci sono volute? Poche, veramente poche! E questo dimostra l'enorme efficacia dell'algoritmo di Euclide. Per sapere il numero delle ricorsioni, modificate la suddetta CF in:

[sourcecode]
List ( A ; If ( B <> 0 ; MCD ( B ; Mod ( A ; B ) ) ; A ) )

[/sourcecode]

ed usatela in un campo calcolato con risultato testo. Otterrete:

[sourcecode]
70

56

14

14

[/sourcecode]

Per spingere al limite le ricorsioni di una CF tail recursive dobbiamo cambiare esempio.

[sourcecode]
// Down ( number ) custom function</p>
If ( number ; Down ( number - 1 ) ; number )

[/sourcecode]

Questa funzione restituisce sempre 0, qualsiasi sia il numero positivo inserito, ma restituisce ? se number > 49998. 

Un altro esempio?

[sourcecode]
// Top ( from ; to )
Let (
v = GetAsNumber ( GetValue ( from ; 1 ) ) ;
If ( v < to ; top (  v + 1 & ¶ & from ; to ) ; from  )
)

[/sourcecode]

Questa funzione restituisce una lista di numeri in ordine decrescente da to a from: abbastanza veloce, in un range limitato. Ma se provate Top ( 1 ; 49999 ), dovrete armarvi di santa pazienza.

1 commento

LASCIA UN COMMENTO

Please enter your comment!
Please enter your name here