Interfaccia corretta per la libreria di calcolatori?

3

Come pratica, sto progettando di implementare una libreria di calcolatori multivariabile. L'idea è che puoi definire una funzione, come f(x, y) = sin(x)^2 + 3*y^3 , e quindi puoi valutarla con valori di variabile specifici (ad esempio f(4, 3) ) o prendere la derivata rispetto a una certa variabile e ottenere un'altra funzione. L'idea è che potrebbe essere utilizzato da un programma di fisica o un'app calcolatrice che esponga più direttamente la funzionalità.

Non sono sicuro di come costruire la migliore interfaccia. Usando lo stile che mi è più familiare, potrei definire la funzione sopra con Function f = new Sum(new Exponent(new Sin(new Variable("x")), 2), new Product(new Constant(3), new Exponent(new Variable("y"), 3) , ma è molto lunga rispetto alla tipica stenografia matematica. Ecco alcuni modi in cui posso immaginare che l'API funzioni:

  1. Function f = new Sum(new Exponent(new Sin(new Variable("x")), 2), new Product(new Constant(3), new Exponent(new Variable("y"), 3) (come prima)
  2. Function f = Sum.create(Exponent.create(Sin.create(Variable.create("x")), Constant.create(2)), ... (come prima ma con metodi di build statici)
  3. Function f = sum(power(sin(getVariable("x")), getConstant(2)), product(getConstant(3), power(getVariable("y"), constant(3))) (più breve, ma richiede un bel po 'di importazioni statiche)
  4. Function f = FunctionGenerator.parse("sin(x)^2 + 3*y^3")

Mi piacciono 4 perché è molto più breve, ma sono diffidente perché raramente lo vedo usato; i due esempi che ho visto che mi vengono in mente sono Regex e MySQL, e sono entrambi fondamentalmente il porting di linguaggi testuali più vecchi. In particolare, Regex sembra avere senso per un'API testuale perché è utilizzata per l'elaborazione del testo.

In breve, mi piace il # 4 ma sto attraversando un periodo difficile per giustificare questa partenza dalla convention.

(Nota: so che l'opzione # 4 richiede un parser.Ho già usato ANTLR, quindi questo non dovrebbe essere un problema.)

    
posta raptortech97 17.09.2014 - 00:40
fonte

3 risposte

6

Parlando ad alto livello, forse creerei l'interfaccia in modo che l'opzione 1 sia il modo "nativo" per costruire il tuo albero delle espressioni. Inoltre, l'opzione 4 potrebbe fornire un'interfaccia opzionale che offre una notazione molto più succinta. Il risultato sarebbe esattamente quello che verrebbe generato manualmente usando l'opzione 1.

    
risposta data 17.09.2014 - 00:47
fonte
4

Coppia di punti.

  1. Dato che conosci già ANTLR probabilmente ti renderai conto che la tua rappresentazione interna sarà un AST, o qualcosa di molto vicino.
  2. L'uso di "nuovo" è disordinato. Meglio usare le fabbriche, per chiarezza di codice.
  3. Sì, avrai bisogno di un parser ma è più bello iniziare le cose costruendo direttamente l'AST. Quindi puoi fare le cose interessanti, come capire come fare la differenza ecc.

Quindi raccomanderei prima:

var ast = AstFactory.create();
var f = ast.add(ast.exp(ast.sin(ast.var("x")), const(2)), ast.mul(ast.const(3), ast.Exp(ast.Var("y"), ast.const(3))

Quindi puoi costruire l'AST in modo efficiente usando un'interfaccia fluente e una notazione postfissa:

var f = AstGenerator.var("x").sin().const(2).exp().const(3).var("y").const(3).exp().mul().add();

E infine, hai ancora bisogno di questo (eventualmente):

var f = FunctionGenerator.parse("sin(x)^2 + 3*y^3")
    
risposta data 17.09.2014 - 06:57
fonte
3

Come sarà usato? Penso che sia necessario consultare i termini dei modelli di utilizzo del codice client.

Probabilmente il codice per un'app calcolatrice non include molte formule complesse. Quindi il problema che stai cercando di affrontare non si presenta davvero. Qualcosa che un'app calcolatrice vorrebbe sia in grado di costruire una mappa di nomi per implementare funzioni e nessuno dei tuoi progetti sembra facilitarli.

Una sorta di sistema di modellazione fisica probabilmente ha formule complesse. Ma hanno anche il problema della collisione dei simboli. Potrei avere E=mc^2 come formula. Ma cosa succede quando sono preoccupato per due oggetti? Non dovrebbero condividere una massa, ma penso che in tutti i tuoi progetti probabilmente lo fanno.

Mi sembra che tu stia progettando un sistema senza una chiara idea di come potrebbe essere il codice del client. Penso che non sia utile. Penso che le librerie come questa siano di solito più utili nel caso in cui siano basate sull'esperienza con le applicazioni di scrittura che userebbero una tale libreria. In questo modo hai un'idea chiara di cosa hai bisogno.

    
risposta data 17.09.2014 - 01:51
fonte

Leggi altre domande sui tag