Perché Python non ha switch?

Se vi siete mai chiesti perchè in python non esiste switch...case, un’ottima risposta la trovate nell’articolo di Lance Finn Helsten nell’ultimo numero di The Python Papers, pubblicato oggi. Ho scaricato il PDF pochi minuti fa e non sono ancora riuscito a leggerlo tutto, ma vi posso assicurare che l’articolo su switch da solo merita il download. Lascio a voi un giudizio sul resto dei contenuti, fatevi sentire magari nei commenti.

Comments

  1. Ah! i soliti pythonisti che dicono che il case è inutile, invece di pensare a migliorarlo 😉

    In ruby il case è basato su un operatore, “===”, il che offre gli stessi vantaggi di una decision table (lookup O(k) è O(1)), con in più la possibilità di usare matching più espressivi, esempio stupido:

    >> def intify(obj)
    >>  case obj
    >>   when /\d+/
    >>    Integer(obj)
    >>   when Integer
    >>    obj
    >>   when Float
    >>    obj.floor
    >>   else
    ?>    obj.to_i
    >>   end
    >> end
    => nil
    >> intify('1')
    => 1
    >> intify(2)
    => 2
    >> intify(3.0)
    => 3
    

    In sostanza, equivale ad usare una lista di funzioni per il match ed una DT per il codice associato.
    A me non piace troppo perché continua ad avere lo stesso problema di tutte le strutture di controllo, la non estensibilità, ma tanto per dire che c’è un mondo oltre C e Java 🙂

  2. Che bello quando i rubyisti trovano una rara occasione per far vedere che il loro linguaggio tiene testa al magnifico, eccezionale, insuperabile Python. 🙂

  3. Mi sono letto l’articolo e non ho capito una cosa di questa sintassi:

    MY_SWITCH = {...}
    def fastSwitch(x):
          return MY_SWITCH..get(x, defaultFunction)()

    come vedete ci sono due PUNTI fra SWITCH e get, forse volevano usarne uno solo? Non capisco il doppio punto….

  4. [OT] magari fatemi sapere come inserire i blocchi di codice come ha fatto gabriele, così evito che il codice appaia tutto sulla stessa linea 😉

  5. Andrea, devi usare normali tag HTML, in questo caso pre. Correggo io a mano.

  6. ludo: ho smesso di competere nel celolunghismo ruby-python-perl da anni.. non trovavo più nessuno che giocasse con me 😉

    andrea: si, a me sembra proprio un refuso, dovrebbe esserci un solo “.” tra MY_SWITCH e get

  7. Walter Franzini says:

    Non sono un esperto di Python, ma mi/vi chiedo come viene gestito dall’implementazione proposta nel paper segnalato da ludo il caso in cui le varie funzioni accettino parametri differenti o abbiano bisogno di modificare variabili differenti?

    Probabilmente la risposta e` ovvia e io sono solo troppo abituato a poter usare lo switch 🙂

  8. Si puo` fare in vari modi, partendo dal semplice uso delle closure per definire le funzioni (che sarebbe quello piu` equivalente). Al fatto che bastarebbe definire le funzioni nel dizionario con *args e/o **kwargs come argomenti in modo da accettare un numero arbitrario di argomenti, appunto.

  9. Walter Franzini says:

    Grazie Valentino,

    mi sembra che la prima delle tue soluzioni metta fuori gioco l’implementazione con fastSwitch. O mi sbaglio?

    Mentre per la secondo sono curioso di sapere come invochi questa funzione che accetta un numero arbitrario di argomenti?

  10. Non necessariamente si mette fuori gioco il fastSwitch. Essendo un dizionario posso popolarlo con le funzioni dopo che ho creato le closures. Lui resta una variabile globale e puo` essere usato come tale (che e` il punto principale, visto che il lookup di un nome globale e` piu` veloce degli altri).

    Riguardo all’invocazione invece non c’e` nulla di particolare. Semplicemente si passano argomenti. *args permette di passare argomenti per posizione mentre **kwargs per nome quindi:

    def funzione(*args, **kwargs):
         print args
         print kwargs
    
    funzione(1,2,3,4,5, arg=1, arg2="ciao", arg3="pippo")
    -> (1,2,3,4,5)
    -> {"arg": 1, "arg2": "ciao", "arg3": "pippo"}
    
  11. riffraff: “ho smesso di competere nel celolunghismo ruby-python-perl da anni”

    Mi hai regalato un sorrisone e una siringata di buonumore… il “celolunghismo” è fantastico! LOL

  12. Neanche in Perl c’è, e credo che sia stato fatto di proposito. In compenso nel “perl style” del camel book (ma potrei sbagliare) sono prodighi di alternative: http://www.perl.com/doc/FMTEYEWTK/style/slide-index.html

  13. in perl non c’era, ma c’è adesso 🙂
    Perl 5.10 ha uno switch statement basato un un generico operatore chiamato “smart matching operator”, che altro non è che la versione perlish del costrutto ruby (per certi versi meglio, per certi peggio, da quel che ne capisco)

Policy per i commenti: Apprezzo moltissimo i vostri commenti, critiche incluse. Per evitare spam e troll, e far rimanere il discorso civile, i commenti sono moderati e prontamente approvati poco dopo il loro invio.