You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs-src/communicate/py-from-fable.md
+19-12Lines changed: 19 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -164,7 +164,7 @@ Here we use the `ImportAll` attribute, to import the module.
164
164
165
165
- step 1: We specify the module we wish to use. Here `alert` means: "import the `alert.py` file".
166
166
- step 2: we create a let binding called `mylib` to map the js library.
167
-
- step 3: we use the `nativeOnly` keyword to say that `mylib` is just a placeholder for the JavaScript native implementation.
167
+
- step 3: we use the `nativeOnly` keyword to say that `mylib` is just a placeholder for the Python native implementation.
168
168
169
169
Now we can use this:
170
170
@@ -486,14 +486,14 @@ type MyStrings =
486
486
myLib.myMethod(Vertical, Horizontal)
487
487
```
488
488
489
-
```js
490
-
//js output
491
-
myLib.myMethod("vertical", "Horizontal");
489
+
```py
490
+
//Python output
491
+
myLib.myMethod("vertical", "Horizontal")
492
492
```
493
493
494
494
## Plain Old JavaScript Objects
495
495
496
-
To create a plain JS object (aka POJO), use `createObj`:
496
+
To create plain Python dictionaries, use `createObj`:
497
497
498
498
```fsharp
499
499
open Fable.Core.PyInterop
@@ -516,7 +516,7 @@ let data =
516
516
```
517
517
518
518
:::{note}
519
-
Since fable-compiler 2.3.6, when using the dynamic cast operator `!!` to cast an anonymous record to an interface, Fable will raise a warning if the fields in the anonymous don't match those of the interface. Use this feature only to interop with JS, in F# code the proper way to instantiate an interface without an implementing type is an [object expression](https://fsharpforfunandprofit.com/posts/object-expressions/).
519
+
Since fable-compiler 2.3.6, when using the dynamic cast operator `!!` to cast an anonymous record to an interface, Fable will raise a warning if the fields in the anonymous don't match those of the interface. Use this feature only to interop with Python, in F# code the proper way to instantiate an interface without an implementing type is an [object expression](https://fsharpforfunandprofit.com/posts/object-expressions/).
520
520
:::
521
521
522
522
```fsharp
@@ -535,7 +535,7 @@ let y: IMyInterface = !!{| foo = "5"; bAr = 4.; baz = Some 0 |}
535
535
let z: IMyInterface = !!{| foo = "5"; bar = 4. |}
536
536
```
537
537
538
-
You can also create a JS object from an interface by using `createEmpty` and then assigning the fields manually:
538
+
You can also create a Python dictinary from an interface by using `createEmpty` and then assigning the fields manually:
539
539
540
540
```fsharp
541
541
let x = createEmpty<IMyInterface> // var x = {}
@@ -546,7 +546,7 @@ x.bar <- 8.5 // val.bar = 8.5
546
546
A similar solution that can also be optimized by Fable directly into a JS object at compile time is to use the `jsOptions` helper:
547
547
548
548
```fsharp
549
-
let x = jsOptions<IMyInterface>(fun x ->
549
+
let x = pyOptions<IMyInterface>(fun x ->
550
550
x.foo <- "abc"
551
551
x.bar <- 8.5)
552
552
```
@@ -579,19 +579,25 @@ it's usually a good idea to inline the function containing the helper.
579
579
580
580
### Dynamic typing: don't read this!
581
581
582
-
Through the use of the tools we just described above, Fable guarantees you shouldn't run into nasty bugs (as long as the interface contracts are correct) because all the code will be checked by the compiler. If it does not compile it either means your Python library does not exist or its path is not good or that your F# implementation lacks something. We do rely on Fable on systems that are used 24/7. We know that if it compiles, it means a 99% chance of running without any problems.
582
+
Through the use of the tools we just described above, Fable guarantees you shouldn't run into nasty bugs (as long as the
583
+
interface contracts are correct) because all the code will be checked by the compiler. If it does not compile it either
584
+
means your Python library does not exist or its path is not good or that your F# implementation lacks something. We do
585
+
rely on Fable on systems that are used 24/7. We know that if it compiles, it means a 99% chance of running without any
586
+
problems.
583
587
584
588
Our motto is: "If it compiles, it works!"
585
589
586
-
Still, like we stated, **interop is a question of trust**. If you trust your Python code and F# code, then maybe it's ok to do things together without further checks. Maybe.
590
+
Still, like we stated, **interop is a question of trust**. If you trust your Python code and F# code, then maybe it's ok
591
+
to do things together without further checks. Maybe.
587
592
588
593
:::{warning}
589
594
Disclaimer: use this at your own risk
590
595
:::
591
596
592
597
#### What is dynamic typing?
593
598
594
-
Fable.Core.PyInterop implements the F# dynamic operators so you can easily access an object property by name (without static check) as follows:
599
+
Fable.Core.PyInterop implements the F# dynamic operators so you can easily access an object property by name (without
600
+
static check) as follows:
595
601
596
602
```fsharp
597
603
open Fable.Core.PyInterop
@@ -607,7 +613,8 @@ printfn "Value: %O" jsObject?(pname) // Access with a reference
607
613
pyObject?myProperty <- 5 // Assignment is also possible
608
614
```
609
615
610
-
When you combine the dynamic operator with application, Fable will destructure tuple arguments as with normal method calls. These operations can also be chained to replicate Python fluent APIs.
616
+
When you combine the dynamic operator with application, Fable will destructure tuple arguments as with normal method
617
+
calls. These operations can also be chained to replicate Python fluent APIs.
<li><p>step 1: We specify the module we wish to use. Here <codeclass="docutils literal notranslate"><spanclass="pre">alert</span></code> means: “import the <codeclass="docutils literal notranslate"><spanclass="pre">alert.py</span></code> file”.</p></li>
716
716
<li><p>step 2: we create a let binding called <codeclass="docutils literal notranslate"><spanclass="pre">mylib</span></code> to map the js library.</p></li>
717
-
<li><p>step 3: we use the <codeclass="docutils literal notranslate"><spanclass="pre">nativeOnly</span></code> keyword to say that <codeclass="docutils literal notranslate"><spanclass="pre">mylib</span></code> is just a placeholder for the JavaScript native implementation.</p></li>
717
+
<li><p>step 3: we use the <codeclass="docutils literal notranslate"><spanclass="pre">nativeOnly</span></code> keyword to say that <codeclass="docutils literal notranslate"><spanclass="pre">mylib</span></code> is just a placeholder for the Python native implementation.</p></li>
718
718
</ul>
719
719
<p>Now we can use this:</p>
720
720
<divclass="highlight-fsharp notranslate"><divclass="highlight"><pre><span></span><spanclass="n">mylib</span><spanclass="o">.</span><spanclass="n">triggerAlert</span><spanclass="w"></span><spanclass="o">(</span><spanclass="s">"Hey I'm calling my js library from Fable > "</span><spanclass="w"></span><spanclass="o">+</span><spanclass="w"></span><spanclass="n">mylib</span><spanclass="o">.</span><spanclass="n">someString</span><spanclass="o">)</span><spanclass="w"></span>
@@ -996,15 +996,15 @@ <h3>StringEnum<a class="headerlink" href="#stringenum" title="Permalink to this
@@ -1024,7 +1024,7 @@ <h2>Plain Old JavaScript Objects<a class="headerlink" href="#plain-old-javascrip
1024
1024
</div>
1025
1025
<divclass="admonition note">
1026
1026
<pclass="admonition-title">Note</p>
1027
-
<p>Since fable-compiler 2.3.6, when using the dynamic cast operator <codeclass="docutils literal notranslate"><spanclass="pre">!!</span></code> to cast an anonymous record to an interface, Fable will raise a warning if the fields in the anonymous don’t match those of the interface. Use this feature only to interop with JS, in F# code the proper way to instantiate an interface without an implementing type is an <aclass="reference external" href="https://fsharpforfunandprofit.com/posts/object-expressions/">object expression</a>.</p>
1027
+
<p>Since fable-compiler 2.3.6, when using the dynamic cast operator <codeclass="docutils literal notranslate"><spanclass="pre">!!</span></code> to cast an anonymous record to an interface, Fable will raise a warning if the fields in the anonymous don’t match those of the interface. Use this feature only to interop with Python, in F# code the proper way to instantiate an interface without an implementing type is an <aclass="reference external" href="https://fsharpforfunandprofit.com/posts/object-expressions/">object expression</a>.</p>
<p>You can also create a JS object from an interface by using <codeclass="docutils literal notranslate"><spanclass="pre">createEmpty</span></code> and then assigning the fields manually:</p>
1044
+
<p>You can also create a Python dictinary from an interface by using <codeclass="docutils literal notranslate"><spanclass="pre">createEmpty</span></code> and then assigning the fields manually:</p>
1045
1045
<divclass="highlight-fsharp notranslate"><divclass="highlight"><pre><span></span><spanclass="k">let</span><spanclass="w"></span><spanclass="nv">x</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">createEmpty</span><spanclass="o"><</span><spanclass="n">IMyInterface</span><spanclass="o">></span><spanclass="w"></span><spanclass="c1">// var x = {}</span><spanclass="w"></span>
<p>A similar solution that can also be optimized by Fable directly into a JS object at compile time is to use the <codeclass="docutils literal notranslate"><spanclass="pre">jsOptions</span></code> helper:</p>
@@ -1079,16 +1079,22 @@ <h2>Plain Old JavaScript Objects<a class="headerlink" href="#plain-old-javascrip
1079
1079
</div>
1080
1080
<sectionid="dynamic-typing-don-t-read-this">
1081
1081
<h3>Dynamic typing: don’t read this!<aclass="headerlink" href="#dynamic-typing-don-t-read-this" title="Permalink to this headline">#</a></h3>
1082
-
<p>Through the use of the tools we just described above, Fable guarantees you shouldn’t run into nasty bugs (as long as the interface contracts are correct) because all the code will be checked by the compiler. If it does not compile it either means your Python library does not exist or its path is not good or that your F# implementation lacks something. We do rely on Fable on systems that are used 24/7. We know that if it compiles, it means a 99% chance of running without any problems.</p>
1082
+
<p>Through the use of the tools we just described above, Fable guarantees you shouldn’t run into nasty bugs (as long as the
1083
+
interface contracts are correct) because all the code will be checked by the compiler. If it does not compile it either
1084
+
means your Python library does not exist or its path is not good or that your F# implementation lacks something. We do
1085
+
rely on Fable on systems that are used 24/7. We know that if it compiles, it means a 99% chance of running without any
1086
+
problems.</p>
1083
1087
<p>Our motto is: “If it compiles, it works!”</p>
1084
-
<p>Still, like we stated, <strong>interop is a question of trust</strong>. If you trust your Python code and F# code, then maybe it’s ok to do things together without further checks. Maybe.</p>
1088
+
<p>Still, like we stated, <strong>interop is a question of trust</strong>. If you trust your Python code and F# code, then maybe it’s ok
1089
+
to do things together without further checks. Maybe.</p>
1085
1090
<divclass="admonition warning">
1086
1091
<pclass="admonition-title">Warning</p>
1087
1092
<p>Disclaimer: use this at your own risk</p>
1088
1093
</div>
1089
1094
<sectionid="what-is-dynamic-typing">
1090
1095
<h4>What is dynamic typing?<aclass="headerlink" href="#what-is-dynamic-typing" title="Permalink to this headline">#</a></h4>
1091
-
<p>Fable.Core.PyInterop implements the F# dynamic operators so you can easily access an object property by name (without static check) as follows:</p>
1096
+
<p>Fable.Core.PyInterop implements the F# dynamic operators so you can easily access an object property by name (without
@@ -1102,7 +1108,8 @@ <h4>What is dynamic typing?<a class="headerlink" href="#what-is-dynamic-typing"
1102
1108
<spanclass="n">pyObject</span><spanclass="o">?</span><spanclass="n">myProperty</span><spanclass="w"></span><spanclass="o"><-</span><spanclass="w"></span><spanclass="mi">5</span><spanclass="w"></span><spanclass="c1">// Assignment is also possible</span><spanclass="w"></span>
1103
1109
</pre></div>
1104
1110
</div>
1105
-
<p>When you combine the dynamic operator with application, Fable will destructure tuple arguments as with normal method calls. These operations can also be chained to replicate Python fluent APIs.</p>
1111
+
<p>When you combine the dynamic operator with application, Fable will destructure tuple arguments as with normal method
1112
+
calls. These operations can also be chained to replicate Python fluent APIs.</p>
0 commit comments