Mantener API versus usar modismos en un puerto

12

Estoy trabajando en un puerto de Python a Rust y encontré un código que no se puede expresar de forma tan natural en Rust como en Python.

Un caso de esto es el uso de parámetros predeterminados:

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

En Rust, puede implementar esto usando un generador:

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,
    }
  }
}

Para usar la clase en Python, es simplemente:

foo = Foo("Hello, World!")

Sin embargo, en Rust, necesitaría escribir algo como:

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

Esto lleva a la pregunta: ¿es mejor mantener una API para un puerto, o es mejor usar expresiones idiomáticas del lenguaje portador? ¿Depende de qué tan conocida sea la API para empezar?

erip
fuente
2
La API de una clase es cómo la usas, no cómo se expresa en código. Entonces, esa traducción tiene un ABI completamente diferente y simplemente inaceptablemente engorroso.
Deduplicador
¿Dónde se dice que eso es óxido idiomático?
Nadir Sampaoli
Lo siento, debo haber entendido mal. Publicó algún código de Rust, junto con un dilema: el clima mantendría una API para un puerto o usaría expresiones idiomáticas del lenguaje de portado . Ese código no se parece a ninguno de esos casos. Si esta es la interpretación correcta, ¿cuál es el propósito de esa muestra de código? ¿Qué está describiendo y cómo se relaciona con la pregunta real?
Nadir Sampaoli

Respuestas:

18

Desea que sus ideas se expresen claramente en el idioma que las alberga. Eso significa usar modismos de lenguaje anfitrión.

Tome la popular biblioteca Underscore: js y lua . El puerto lua es funcionalmente equivalente en su mayor parte . Pero cuando es apropiado, las implementaciones son ligeramente diferentes. Por ejemplo:

_.toArray()

se convierte

_.to_array()

Este cambio hace que el nombre de la función se sienta más nativo para los programadores de Lua.

Del mismo modo, _.each () requiere un objeto, una matriz o algo similar a una matriz en JavaScript, pero _.each () en Lua también puede tomar un iterador, un mecanismo que no estaba disponible en JavaScript cuando la biblioteca original de subrayado fue creado.

El autor de Lua tradujo sensatamente lo que el autor original habría querido si lo hubiera escrito en Lua. Esa es la clave Pregúntese acerca de la intención original y luego implemente esa intención en su idioma de elección: modismos y todo. Dependiendo del idioma de origen y destino, esto puede significar agregar, editar o eliminar funciones.

Recuerde que los usuarios de varios idiomas serán raros. La mayoría de los usuarios usarán un idioma u otro. Para ellos, las diferencias no importan. Si alguien usa ambos, probablemente sean lo suficientemente sofisticados como para apreciar su traducción. No es diferente a traducir idiomas hablados. Algunas ideas no son directamente traducibles. Los mejores traductores se apegan a la intención del original, no a una traducción literal condenada palabra por palabra.

Roger escaso
fuente