Mantenere l'API rispetto all'uso dei modi di dire in una porta


12

Sto lavorando su una porta da Python a Rust e mi sono imbattuto in un codice che non può essere espresso naturalmente in Rust come in Python.

Un caso è l'utilizzo dei parametri predefiniti:

class Foo:
  def __init__(self, a="Hello"):
    self._a = a

In Rust, è possibile implementarlo utilizzando un builder:

struct FooBuilder {
  a: &'static str,
}

struct Foo {
  _a: &'static str
}

impl FooBuilder {
  fn new() -> FooBuilder {
    FooBuilder {
      a: "Hello",
    }
  }

  fn change_a(self, new_a: &'static str) -> FooBuilder {
    FooBuilder {
      a: new_a,
      ..self
    }
  }

  fn build(self) -> Foo {
    Foo {
      _a: self.a,
    }
  }
}

Per usare la classe in Python, è semplicemente:

foo = Foo("Hello, World!")

Tuttavia, in Rust, dovresti scrivere qualcosa del tipo:

let foo = FooBuilder::new().change_a("Hello, World!").build();

Questo porta alla domanda: è meglio mantenere un'API per una porta o è meglio usare modi di dire del linguaggio di porting? Dipende da quanto è noto l'API per cominciare?


2
L'API di una classe è come la usi, non come viene espressa nel codice. Quindi, quella traduzione ha un ABI nettamente diverso e semplicemente inaccettabilmente ingombrante.
Deduplicatore,

Dove si dice che sia ruggine idiomatica?
Nadir Sampaoli,

Mi dispiace, devo aver frainteso. Hai pubblicato del codice Rust, insieme a un dilemma: tempo manterresti un'API per una porta o useresti modi di dire della lingua di porting . Quel codice non assomiglia a nessuno dei due casi. Se questa è l'interpretazione corretta, qual è lo scopo di questo esempio di codice? Cosa sta descrivendo e in che modo si collega alla domanda reale?
Nadir Sampaoli,

Risposte:


18

Vuoi che le tue idee siano espresse chiaramente nella lingua che le ospita. Ciò significa utilizzare i linguaggi della lingua host.

Prendi la popolare libreria Underscore: js e lua . La porta lua è funzionalmente equivalente per la maggior parte . Ma quando è appropriato, le implementazioni sono leggermente diverse. Per esempio:

_.toArray()

diventa

_.to_array()

Questa modifica rende il nome della funzione più nativo dei programmatori Lua.

Allo stesso modo, _.each () richiede un oggetto, un array o qualcosa di simile ad un array in JavaScript, ma _.each () in Lua può anche prendere un iteratore - un meccanismo che non era disponibile in JavaScript quando la libreria originale di Underscore è stata creata.

L'autore di Lua tradusse sensibilmente ciò che avrebbe voluto l' autore originale se l'avessero scritto in Lua. Questa è la chiave. Chiediti dell'intento originale e poi implementa quell'intento nella tua lingua preferita - idiomi e tutto il resto. A seconda della lingua di origine e di destinazione, ciò può significare aggiungere, modificare o rimuovere funzionalità.

Ricorda che gli utenti multilingue saranno rari. La maggior parte degli utenti utilizzerà una lingua o l'altra. Per loro, le differenze non contano. Se qualcuno usa entrambi, è probabilmente abbastanza sofisticato da apprezzare la tua traduzione. Non è diverso dalla traduzione delle lingue parlate. Alcune idee non sono direttamente traducibili. I migliori traduttori si attengono all'intento dell'originale, non una traduzione letterale condannata parola per parola.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.