Fable: Hilfe bei der Entwicklung von Fable 2

Erstellt am 21. März 2018  ·  37Kommentare  ·  Quelle: fable-compiler/Fable

Ich bin mir nicht sicher, ob sich der Zweig dev2.0 bereits in einem Zustand befindet, in dem ich um Hilfe rufen kann, aber ich werde es trotzdem tun :wink: Ich liste unten die wichtigsten Änderungen auf, die in diesem Zweig passieren, wie können Sie schnell testen und welche Aufgaben für das erste Alpha-Release anstehen. Wenn Sie daran interessiert sind, bei einem von ihnen zu helfen, kommentieren Sie bitte unten, damit ich weitere Details für die Zusammenarbeit angeben kann 💪

Nicht umfassende Liste der wichtigsten Änderungen

  • Fable AST enthält jetzt einige der gängigsten Konstrukte in F# (Liste, Option...), sodass es bei Bedarf einfacher ist, ihre Darstellung in JS zu ändern. Außerdem behält der AST jetzt Typinformationen vom F#-Compiler bei.
  • Records und Unions werden nicht als JS _classes_ kompiliert, sondern als einfache Objekte bzw. Arrays.
  • Alle Typmethoden sind jetzt als JS-Modulfunktionen kompiliert, um eine bessere Kompatibilität mit Tree-Shaking zu gewährleisten (hoffentlich sollte es auch JS-Engines helfen, den Code zu optimieren). Einzige Ausnahme sind Override-Methoden (ToString, Equals), die an den Prototyp angehängt sind. Außerdem werden verschachtelte Modulfunktionen als Funktionen des Datei-Root-Moduls mit verstümmelten Namen kompiliert.
  • Wenn eine Instanz in ein Interface umgewandelt wird, wird es mit einem Objekt umschlossen, das die Interface-Funktionen enthält, dies verhindert Namenskonflikte zwischen den Interfaces (und ist auch notwendig, da Methoden nicht mehr an den Prototyp angehängt sind).
  • Einige Module in fable-core (wie List oder Array) sind jetzt in F# geschrieben
  • Optimierungen, die auf den Fable AST angewendet werden, sind jetzt isolierte Durchgänge in FableTransforms . Dies sollte den Code wartungsfreundlicher machen als Fable 1, wo Optimierungen normalerweise an mehreren Stellen angewendet werden (insbesondere die reibungslose Optimierung, die in Fable 2 hoffentlich viel besser funktioniert). Im letzten Fable2Babel-Durchlauf müssen jedoch noch einige Optimierungen vorgenommen werden: Tail-Calls und Entscheidungsbäume (Pattern-Matching).

Probiere es schnell aus

  • Klonen Sie das Repository, falls noch nicht geschehen
  • git checkout dev2.0
  • cd src/tools
  • bash quicktest.sh --build-core

Dadurch wird die Datei QuickTest.fs im selben Ordner kompiliert und ausgeführt. Fühlen Sie sich frei, es als Spielwiese zu nutzen, um die Funktionen von Fable 2 zu testen (aber bitte nicht in Ihre PRs aufnehmen). Beim zweiten Mal, wenn src/js/fable-core Dateien nicht geändert wurden, können Sie einfach bash quicktest.sh ausführen (wenn sich src/dotnet/Fable.Compiler Dateien nicht geändert haben, können Sie auch bash quicktest.sh --no-build ausführen, aber mit 2.1.300-preview1 sollte das Erstellen eines Projekts ohne Änderungen sowieso ziemlich schnell sein).

Unter Windows sollten Sie das Skript mit Git-Bash ausführen können.

Ausstehende Aufgaben

  • Es gibt eine Reihe von TODO!!! Kommentaren, die über den Code verteilt sind, die ich wahrscheinlich selbst behandeln sollte.

  • Da Plugins nicht in der ersten Alpha-Version enthalten sein werden, verwenden Tests jetzt die Expecto API , die viel einfacher mit JS-Testläufern geteilt werden kann. Ich habe schon einige Dateien konvertiert (ArithmeticTests, ArrayTests, ListTests), aber die meisten warten noch auf Liebe. Ich habe Regex verwendet, um die Signatur der Methoden in testCase zu ändern, aber wahrscheinlich ist es eine gute Idee, ein Skript dafür zu schreiben. Eine der größten Herausforderungen besteht darin, dass, da Tests jetzt Werte in einer Liste sind, zusätzliche Funktionen, die in der Mitte der Datei erscheinen, nach oben verschoben werden müssen, was in einigen Fällen andere Werte überschatten kann.

  • Set- und Map-Module in fable-core müssen auf F# portiert werden. Ich habe es teilweise für Set gemacht (die Karte kann auch aus dem FunScript-Repository entnommen werden, von dem ich sie ursprünglich gestohlen habe ). Wir müssen sicherstellen, dass sie korrekt in JS kompiliert sind, die öffentlichen Funktionsnamen korrekt angezeigt werden, prüfen, ob wir Methoden aus den vorherigen .ts-Dateien (gespeichert in src/tools/old ) portieren müssen und ob die Tests korrekt funktionieren .

  • Da sich das AST so stark geändert hat, müssen die meisten Ersatzmodule neu geschrieben werden . Ich habe schon ungefähr 1000 Zeilen gemacht und es sind noch tausend zu gehen. Dies ist eine etwas mühsame Aufgabe, aber wenn jemand verrückt genug ist, es zu übernehmen, lassen Sie es mich bitte wissen. Vielleicht ist der schnellste Weg, eine Bildschirmfreigabesitzung durchzuführen, um Ihnen zu zeigen, was zu tun ist, und dann den restlichen Code aufzuteilen, damit wir schneller fertig werden können.

Dinge, die in der ersten Alpha-Version nicht enthalten sein werden: Bigint, Reflection, Plugins.

Ich hoffe das waren jetzt genug Infos, vielen Dank für eure Hilfe im Voraus!

dev2.0 help wanted

Hilfreichster Kommentar

Nur zur Info, wenn jemand die Testdateien portiert, muss ich nicht SetTests.fs und MapTests.fs portieren, ich werde es tun, um die Modulintegration zu testen.

Wenn Sie VSCode verwenden, können Sie auch die Mehrfachauswahl verwenden, um die gesamte Arbeit in einer Datei gleichzeitig zu erledigen. Ein Skript zu schreiben scheint hier etwas übertrieben zu sein :).

2018-04-18 15 14 27

Alle 37 Kommentare

@alfonsogarciacaro Ich denke, ich werde die und Map-Module in der Fable-Core- Aufgabe nehmen. Können Sie mir bitte eine Anleitung geben oder mich auf die teilweise portierten Set hinweisen, damit ich mich hier inspirieren lassen kann :) ?

Nur zur Erinnerung, es gibt viele repos , dass wir stahlen inspirieren aus,

  1. Der offiziellen Kernbibliothek von visualfsharp ähnelt die Kartenimplementierung wirklich der von FunScript:
    https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp/FSharp.Core/map.fs
  2. OCaml/BucleScripts, es gibt nicht viele Unterschiede zwischen F# und der Kernsyntax von OCaml, ich denke, wir können sie leicht nach F# portieren.
    https://github.com/BuckleScript/bucklescript/blob/master/jscomp/stdlib/map.ml

Danke, @zaaack. Ja, die FunScript-Datei stammt ursprünglich aus FSharp.Core. Ich bin mir nicht sicher, ob es veraltet ist, aber ich bevorzuge es, weil es bereits funktioniert ( Map.ts in Fable 1 war ursprünglich auch eine Übersetzung davon) und ich denke, es hat bereits einige der Dinge abgeschnitten, die wir nicht haben brauchen in JS. Was Bucklescript angeht, bin ich mir nicht sicher, ob die Tatsache, dass Module Werte in OCaml sind, problematisch sein könnte, auch Map in F# muss mit einigen Schnittstellen übereinstimmen, und was mich am meisten Zeit gekostet hat, ist, dass Typen mit benutzerdefiniertem Vergleich ordnungsgemäß als Schlüssel funktionieren, was Ich denke, es ist auch etwas anders in OCaml.

Übrigens, Bigint stammt tatsächlich von FSharp.Core, aber ich denke, wir portieren in einer späteren Version.

Danke @zaaack, das werde ich bei der Arbeit am Port berücksichtigen.

Hallo Alfonso, ich würde gerne beim Expecto-Testteil helfen

Das ist großartig @EdouardM , danke! Es wäre großartig, wenn Sie ein Skript schreiben könnten, um den größten Teil der Konvertierung automatisch durchzuführen. Wenn Sie möchten, können wir eine kurze Bildschirmfreigabesitzung durchführen, um zu zeigen, was zu tun ist :)

Klar brauche ich einen kurzen Kick-Off, um in die Spur zu kommen.

Wären Sie heute Abend ab 18:30 Uhr Paris-Madrid-Zeit verfügbar?
oder am Sonntag?

Wenn ja, senden Sie mir bitte eine Einladung zu einem Skype-Anruf.

Vielen Dank
douard

Le ven. 23. März 2018 à 11:43, Alfonso Garcia-Caro [email protected]
ein ekrit:

Das ist großartig @EdouardM https://github.com/edouardm , danke! Es würde
wäre großartig, wenn du ein Skript schreiben könntest, um das Beste aus der Konvertierung zu machen
automatisch. Wenn Sie möchten, können wir eine kurze Bildschirmfreigabesitzung durchführen
zeigen was zu tun ist :)


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/fable-compiler/Fable/issues/1370#issuecomment-375619541 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AG_t3dil59Mz38u4cCN9f0JEZMyK7OLRks5thNHPgaJpZM4S03ig
.

Meine E-Mail lautet: Edouard. [email protected]

Le ven. 23. März 2018 à 11:43, Alfonso Garcia-Caro [email protected]
ein ekrit:

Das ist großartig @EdouardM https://github.com/edouardm , danke! Es würde
wäre großartig, wenn du ein Skript schreiben könntest, um das Beste aus der Konvertierung zu machen
automatisch. Wenn Sie möchten, können wir eine kurze Bildschirmfreigabesitzung durchführen
zeigen was zu tun ist :)


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/fable-compiler/Fable/issues/1370#issuecomment-375619541 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AG_t3dil59Mz38u4cCN9f0JEZMyK7OLRks5thNHPgaJpZM4S03ig
.

Dinge, die in der ersten Alpha-Version nicht enthalten sein werden: Bigint, Reflection, Plugins.

Nur neugierig, gibt es eine Roadmap / einen Plan, um diese Dinge nach der Alpha aufzunehmen?

@jgrund Keine spezifische Roadmap, aber bigint sollte einfach hinzuzufügen sein (einfach den Code von FSharp.Core portieren) und Reflection sollte auch für die stabile Veröffentlichung bereit sein. Über Plugins möchte ich Informationen über deren Verwendung sammeln und dann gemeinsam entscheiden, wie wir sie einbringen oder ob sie überhaupt benötigt werden.

Danke dafür! Ich musste eine kleine Änderung an quicktest.sh vornehmen, damit es in Git-Bash funktioniert:
https://github.com/fable-compiler/Fable/blob/07ddd104cbeb6ad7adf98b6600ac3fe4d1fcfd70/src/tools/quicktest.sh#L30 -L33
Zeile 32 geändert zu einfach:
./quickfsbuild.sh --no-build
da die bash darin (die ich sowieso nicht brauche?) WSL veranlasste, stattdessen zu versuchen, zu starten, was ich nicht eingerichtet habe.

Hallo @EdouardM! Das haben wir bei fsharpX über die Aktualisierung der Tests besprochen:

  • Verwendung der Expecto-API (wird tatsächlich für JS in Mokka übersetzt)
  • Verwenden Sie die Regex let ``(.*)``.*= und den Ersatz testCase "$1" <| fun () -> , um die Signatur der Tests zu ändern
  • Entfernen Sie die Attribute [<Test>] , [<TestFixture>]
  • Fügen Sie die Datei zu Main.fsproj und allTests in tests/Main/Main.fs hinzu
  • Besondere Sorgfalt ist für Async und Funktionen in der Mitte der Tests erforderlich, darüber können wir später sprechen.

@alfonsogarciacaro Ich lese den Quellcode des dev2.0-Zweigs und versuche, der "Verrückte" zu sein, um am Rest von Replacement.fs da die anderen beiden belegt sind 😄. Ich habe einige Probleme beim Portieren der parse Funktion von der alten Replacement.fs , die parse Funktion hängt von returnType die in Fable.ApplyInfo in Fable existiert 1.0, aber ich kann es nicht in CallInfo finden. Ich weiß nicht, wie ich damit umgehen soll, könnten Sie mir helfen?

Hier ist mein Commit:
https://github.com/fable-compiler/Fable/compare/dev2.0...zaaack :dev2.0?expand=1#diff-a34e57b30a53951ff9b99ce4076feaa4R1390

Das wäre toll @zaaack , vielen Dank. Und ja, sorry, ich ändere die Signatur der Funktionen bei Ersetzungen ein wenig, damit sie eher wie Funktionen in anderen Modulen aussehen, wo normalerweise die ersten drei Argumente stehen (der Kontext kann auch an zweiter Stelle kommen):

let myFableHelper (com: ICompiler) (range: SourceLocation option) (typ: Type) ... =

Aus diesem Grund habe ich den Rückgabetyp (und den Bereich) von CallInfo auf die ersten Argumente der Funktion verschoben. Sie können etwas wie let parse com r t info thisArg args = (ja, ich verwende normalerweise nur t und ich stimme zu, dass es nicht sehr aussagekräftig ist).

Ich arbeite auch im Ersatzmodul. Ich kann die Sammlungen (Seq, List, Array) angehen, während Sie die anderen Funktionen erledigen, was denken Sie?

Ich habe kürzlich einen statischen Typ Helper hinzugefügt, um statische Member mit optionalen Parametern zu verwenden. Bitte sehen Sie sich den vorhandenen Code an, um zu sehen, wie die Helfer InstanceCall , CoreCall ... verwendet werden. Weitere Hinweise:

  • Es ist wichtig, die Argumenttypen richtig zu übergeben (insbesondere wenn es Funktionen gibt) für die reibungslose Optimierung, die zu einem späteren Zeitpunkt erfolgt. Wenn Argumente nicht geändert werden, übergeben Sie sie direkt von CallInfo . Wenn dies der Fall ist, müssen arg-Typen neu berechnet werden.
  • ThisArg ist optional. Wenn vorhanden, wird es an erster Stelle bestanden. In Fable 2 werden Typinstanzmember tatsächlich als statische Funktionen kompiliert und deshalb wird this als Argument übergeben. ArgTypes nicht ThisArg .
  • Wenn jedoch die Art InstanceCall angegeben wird, wird der Ausdruck ThisArg als tatsächlicher Instanzaufruf kompiliert: thisArg.member(arg1, arg2...) .

Dies sollte fürs Erste reichen :) Bitte kontaktieren Sie mich, wenn Sie Fragen haben und nochmals vielen Dank für Ihre Hilfe!

Danke für deine schnelle und ausführliche Antwort, werde ich morgen ausprobieren.

Ich arbeite auch im Ersatzmodul. Ich kann die Sammlungen (Seq, List, Array) angehen, während Sie die anderen Funktionen erledigen, was denken Sie?

Großartig, ich denke, ich kann werktags zwei Stunden und am Wochenende den ganzen Tag verbringen, meistens.

Nur zur Info, wenn jemand die Testdateien portiert, muss ich nicht SetTests.fs und MapTests.fs portieren, ich werde es tun, um die Modulintegration zu testen.

Wenn Sie VSCode verwenden, können Sie auch die Mehrfachauswahl verwenden, um die gesamte Arbeit in einer Datei gleichzeitig zu erledigen. Ein Skript zu schreiben scheint hier etwas übertrieben zu sein :).

2018-04-18 15 14 27

Danke Maxime, ich werde die Konvertierungen der Testdateien übernehmen.
Edouard

Am 18. April 2018 um 15:16 Uhr schrieb "Maxime Mangel" [email protected] :

Nur zur Info, wenn jemand die Testdateien portiert, muss sie nicht portiert werden
SetTests.fs und MapTests.fs Ich werde es tun, um die Modulintegration zu testen.

Wenn Sie VSCode verwenden, können Sie auch die Mehrfachauswahl verwenden, um die gesamte Arbeit zu erledigen
auf einmal in einer Datei. Ein Skript zu schreiben scheint ein bisschen übertrieben zu sein
Hier :).

[Bild: 18.04.2018 15 14 27]
https://user-images.githubusercontent.com/4760796/38934173-59a5fc84-431b-11e8-81be-13f624e72817.gif


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/fable-compiler/Fable/issues/1370#issuecomment-382382463 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AG_t3YjH5jvU1CXc-27gpz4-tGQNC7AHks5tpzyegaJpZM4S03ig
.

Hallo zusammen nochmal! Wir müssen noch die folgenden Methoden in src/js/fable-core/List.fs implementieren (beachten Sie, dass es sich um eine F#-Datei handelt, die jedoch in JS verteilt wird):

  • [x] abschneiden
  • [x] Verkettung
  • [ ] zurück finden
  • [ ] findIndexZurück
  • [ ] tryFindBack
  • [ ] tryFindIndexBack
  • [x] indiziert
  • [ ] mapFold
  • [ ] mapFoldBack
  • [x] tryItem
  • [x] entfalten
  • [x] splitAt

Diese sind implementiert, aber die Tests bestehen nicht:

  • [x] foldBack2
  • [x] Partition

Diese sind etwas speziell, da Fable IEqualityComparer als zusätzliches Argument einfügen muss. Ich kann es selbst tun, aber wenn Sie mutig genug sind, können Sie sort als Beispiel nehmen :

  • [x] verschieden
  • [x] eindeutigBy
  • [ ] gruppiere nach
  • [ ] countBy
  • [ ] enthält
  • [ ] außer

Ich habe die fehlgeschlagenen Tests in die Datei QuickTest.fs eingefügt , sodass Sie Fable + fable-core neu kompilieren und die Tests ausführen können, indem Sie einfach Folgendes eingeben:

cd src/tools
sh quicktest.sh --build-core

Irgendwelche Freiwilligen? ;) @valery-vitko @zaaack

Ich werde sehen, was ich dieses Wochenende machen kann.

Ich bin leider vollgepackt für die kommenden Wochen. (Und meistens mit nicht-programmierbezogenem Zeug 😢) . Viel Spaß ohne mich, Jungs.

Ich habe die partition und foldBack2 in #1405 korrigiert.
Ich werde versuchen, einige andere Low-Hanging-Funktionen auszuführen, truncate und indexed .

Implementiert unfold , tryItem , splitAt und concat .

Hi! In der obigen Liste fehlen noch einige Methoden. Arbeitet jemand an ihnen? Wenn nicht, probiere ich sie aus :+1:

@alfonsogarciacaro Entschuldigung, dass ich dachte, sie sind alle vergeben, den Rest übernehme ich.

PR: https://github.com/fable-compiler/Fable/pull/1406

Frage nach dem neuen Umgang mit Methoden und Schnittstellen; wie wird folgendes gehandhabt?

type Base () =
  abstract M: unit -> string
  default __.M () = "base"

type A () =
  inherit Base ()
  member __.M () = "a" // NOTE: Not override, hides parent M

type B () =
  inherit Base ()
  override __.M () = "b"

let a = A ()
let b = B ()

printfn "%s" <| (a :> Base).M ()
printfn "%s" <| (b :> Base).M ()

Fable 2 implementiert eigene Member als Modulfunktionen und löst die Referenzen zur Kompilierzeit auf. Allerdings werden virtuelle Methoden an den JS-Prototyp angehängt, sodass sie auch nach dem Upcasting des Objekts aufgerufen werden können. Diese leicht erweiterte Version Ihres Codes (um zu zeigen, wie ein Objekt das übergeordnete Element aufrufen kann):

type Base () =
  abstract M: unit -> string
  default __.M () = "base"

type A () =
  inherit Base ()
  member __.M () = base.M() + " + a" // NOTE: Not override, hides parent M

type B () = 
  inherit Base ()
  override __.M () = base.M() + " + b"

let a = A ()
let b = B ()

printfn "A:        %s" <| a.M ()
printfn "A upcast: %s" <| (a :> Base).M ()
printfn "B:        %s" <| b.M ()
printfn "B upcast: %s" <| (b :> Base).M ()

Kompiliert mit der neuesten dotnet-fable 2.0.0-alpha wird:

function Base() {}

function Base$$$$002Ector() {
  return this != null ? Base.call(this) : new Base();
}

Base.prototype.M = function () {
  return "base";
};

function A() {
  Base$$$$002Ector.call(this, null);
}

(0, _Types.inherits)(A, Base);

function A$$$$002Ector() {
  return this != null ? A.call(this) : new A();
}

function A$$M(__$$1) {
  return Base.prototype.M.call(this) + " + a";
}

function B() {
  Base$$$$002Ector.call(this, null);
}

(0, _Types.inherits)(B, Base);

function B$$$$002Ector() {
  return this != null ? B.call(this) : new B();
}

B.prototype.M = function () {
  return Base.prototype.M.call(this) + " + b";
};

const a = exports.a = A$$$$002Ector();
const b = exports.b = B$$$$002Ector();
(0, _String.toConsole)((0, _String.printf)("A:        %s"))(A$$M(a));
(0, _String.toConsole)((0, _String.printf)("A upcast: %s"))(a.M());
(0, _String.toConsole)((0, _String.printf)("B:        %s"))(b.M());
(0, _String.toConsole)((0, _String.printf)("B upcast: %s"))(b.M());

Und druckt:

A:        base + a
A upcast: base
B:        base + b
B upcast: base + b

@alfonsogarciacaro Gibt es eine Möglichkeit, die Methode -> Modulkonvertierung vollständig zu deaktivieren und das saubere Ergebnis von Fable 1 zu erhalten?

@vbfox Nein, tut mir leid. Dies würde die Funktionsweise von Fable 2 stark beeinflussen und leider habe ich nicht die Ressourcen, um Compiler-Flags zu verwalten, um verschiedene Ausgaben zu generieren :/

Ich verstehe das Ressourcenproblem vollständig, aber es ist traurig, da es die Kompatibilität zwischen Fable und der JS-Welt zumindest bei der Verwendung von Klassen überall beeinträchtigt:

  • Erstellen eines npm-Pakets mit Fable für den JS-Verbrauch
  • Die Verwendung mehrerer Sprachen für den Zugriff auf eine fabelhaft generierte Klasse (Typoskript) oder muss sehr seltsame Bindungen haben ...

(Fälle, in denen externe Bibliotheken Methodenerkennung durchführen, erfordern auch eine Schnittstellenerstellung, aber dies ist meistens eine gute Praxis.)

Es geht auch weg von JS, auf das man zumindest für den Unterricht stolz sein kann - auch wenn es uns nicht so wichtig ist ;)

Ja, der generierte Code wird in Fable 2 etwas _weniger schön_ sein. Aber es gibt andere Vorteile (besseres Baumschütteln, statischer Versand), die diese Tatsache hoffentlich kompensieren werden. Das Erstellen von Bibliotheken in Fable für den JS-Verbrauch wird immer noch möglich sein, obwohl ich kein tatsächliches Beispiel dafür gesehen habe. Und ich habe es bereits aufgegeben, Typescript in meinen Fable-Projekten zu verwenden, weil es immer kompiliert wird, wenn ich versuche, eine .fs-Datei zu importieren;)

Die Interoperabilität mit JS sollte über Schnittstellen erfolgen. Fable generiert jetzt Objekt-Wrapper mit unverfälschten Namen für die Schnittstellen, damit Sie sie verwenden können, um Typen an JS oder andere Sprachen zu senden.

@alfonsogarciacaro Ich wollte wirklich mit Fable erstellte Bibliotheken für den Konsum in JS erstellen, aber es war so ein großer Schmerz, dass ich es aufgegeben habe. Das ist der Hauptgrund, warum ich Fable nicht viel mehr benutze, als ich es derzeit tue. Ich habe festgestellt, dass es nur zum Erstellen von Apps funktioniert (ob Web oder nicht).

Danke für die Bestätigung @Alxandr. Es war also schon in Fable 1 schmerzhaft, was bedeutet, dass Fable 2 es nicht noch schlimmer machen kann ;)

@alfonsogarciacaro irgendwie wahr. Und ich glaube nicht, dass der Wechsel zur Statik eine Rolle spielen wird (weil die Interface-Objekte eine ziemlich gute Lösung sind). Aber ich denke, es könnte rechtfertigen, darüber zu sprechen, WARUM es massiv schmerzhaft ist, weil ich denke, dass einiges davon durch Fable 2 gelöst werden könnte Dateien das heißt). Das heißt, wenn ich eine Bibliothek und eine in F# erstellte App habe, habe ich jetzt zwei Kopien von Map und List usw. Und Sie haben auch instanceof .. .

Wahr. Tatsächlich haben wir irgendwann versucht, dieses Problem zu lösen (in Fable 0.7, glaube ich, als fable-core und Fable selbst über npm verteilt wurden), aber fable-core hat sich sehr verändert und die richtige Verwaltung von Versionen war ein Albtraum (wir mussten auch Versionen behalten .) für verschiedene Modulsysteme). Die Situation ist viel besser, da Fable 1 Fable-Core-Dateien einfach vom Compiler injiziert werden und wir die Dateien immer synchron haben. Ich glaube nicht, dass das Erstellen von Fable-Bibliotheken für npm, die auch von Fable nativ verwendet werden sollen, machbar ist. Sie erstellen entweder eine JS-Bibliothek (wobei eine JS-API-Oberfläche verfügbar gemacht und vorzugsweise gebündelt wird) oder Sie schreiben eine Fable/F#-Bibliothek, die über Nuget verteilt wird.

Das JS-Ökosystem ist sehr breit gefächert und Fable eröffnet viele Möglichkeiten für F#. Leider ist meine Reichweite begrenzt und ich kann bei Designentscheidungen nicht alles berücksichtigen. Bisher ist die Einführung von Fable in verschiedenen Bereichen: Elmish Web-Apps, React Native, Electron... in der Regel den Mitwirkenden zu verdanken, die die App/Bibliotheken/Tools erstellt haben, und dann haben wir zusammengearbeitet, um die Erfahrung zu vereinfachen. Aber ich habe das noch nicht für JS-Bibliotheken gesehen, die mit Fable erstellt wurden, abgesehen von ein paar kleinen Beispielen.

Ja, nein, das verstehe ich vollkommen. Meine "be-all-end-all" -Lösung wäre wahrscheinlich eine Situation, in der Sie Fable-Core (andy F#/js-Bibliotheken) auf einem CI erstellen und gleichzeitig in NuGet und NPM veröffentlichen. Auf diese Weise würden Sie auch keine F#-Quelldateien auf Nuget benötigen (Sie hätten nur Build-Metadaten, aber Sie benötigen den npm-Importnamen). Es müssen jedoch viele Teile zusammenkommen, damit dies funktioniert, und es kann erforderlich sein, eine Reihe von Metadaten im Nuget-Paket zu speichern (Zuordnung zu den generierten JS-Funktionsnamen).

Also, ich habe heute viel über die neue Fable-Ausgabe nachgedacht und mir ein paar Vielleicht-Probleme ausgedacht, die ich ansprechen möchte, falls sie nicht berücksichtigt wurden:

Klassen vs. Funktionen

Ich bin selbst kein großer Fan von Klassen in JS, sie erfüllen jedoch einen wichtigen Zweck, der mit Funktionen (soweit ich weiß) nicht erreicht werden kann, nämlich die Erweiterung nativer Klassen (wie Map oder Array ). Ich gehe jetzt davon aus, dass die Hauptgründe für die Verwendung von Funktionen anstelle von Klassen die Tatsache sind, dass Sie mit mehreren Konstruktoren umgehen müssen, aber ich bin mir ziemlich sicher, dass dies auf andere Weise gelöst werden kann (ich werde mir das noch einmal etwas genauer ansehen Morgen). Nun, um es klarzustellen, ich rede nicht davon, wieder alles an den Prototypen zu befestigen. Ich spreche nur davon, den primären (oder synthetischen) Konstruktor zu einer Klasse zu machen. Die Möglichkeit, die Konstruktoren ohne new aufzurufen, ist meiner Meinung nach ein ziemlich strittiger Punkt, wenn man bedenkt, dass F# eine typisierte Sprache ist und Fable in der Lage sein sollte, statisch herauszufinden, ob es new ausgeben muss

Schnittstellenguss und Typprüfungen

Ich habe Code gesehen, der gut mit Typhierarchien umgeht und die Typprüfung und das Aufrufen virtueller Member ermöglicht, was alles ganz nett ist, aber wie funktioniert die neue Ausgabe mit Schnittstellen in Vermutungen mit Typprüfungen? Nehmen Sie zum Beispiel den folgenden Code:

type IFoo =
  abstract Foo: string

type IBar =
  abstract Bar: string

type FooBar () =
  interface IFoo with
    member __.Foo = "foo"

  interface IBar with
    member __.Bar = "bar"

let check (t: bool) =
  if not t then failwithf "test failed"

let test () =
  let foobar = FooBar ()
  let foo = foobar :> IFoo
  let bar = foobar :> IBar
  let obj = foobar :> obj

  check (foo :? FooBar)
  check (bar :? FooBar)
  check (foo :? IBar)
  check (bar :? IFoo)
  check (obj :? IFoo)
  check (obj :? IBar)
  ()

Wir können dieses Problem jetzt schließen, vielen Dank an alle für Ihre Hilfe bei der Veröffentlichung von Fable 2!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

jwosty picture jwosty  ·  3Kommentare

MangelMaxime picture MangelMaxime  ·  3Kommentare

funlambda picture funlambda  ·  4Kommentare

MangelMaxime picture MangelMaxime  ·  3Kommentare

alfonsogarciacaro picture alfonsogarciacaro  ·  3Kommentare