|
| 1 | +@tangler ex1 = examples/embedc/ex1.flx |
| 2 | +@title Embedding C++ |
| 3 | +@h1 Basics |
| 4 | +Felix is a unique language in that, unlike other languages, it does |
| 5 | +not have any primitive types. |
| 6 | + |
| 7 | +Instead, Felix provides machinery to <em>lift</em> types from C++ code. |
| 8 | +This means Felix is really a C++ meta-programming language. |
| 9 | + |
| 10 | +I will show the basics here but first a caveat: we have to use weird |
| 11 | +names for things to avoid conflicts with the Felix standard library. |
| 12 | + |
| 13 | +@tangle ex1 |
| 14 | +type cplx = "::std::complex<double>" |
| 15 | + requires header '#include <complex>' |
| 16 | +; |
| 17 | +ctor cplx : double * double = |
| 18 | + "::std::complex<double>($1,$2)" |
| 19 | +; |
| 20 | +fun + : cplx * cplx -> cplx = "$1+$2"; |
| 21 | +fun - : cplx * cplx -> cplx = "$1-$2"; |
| 22 | +fun * : cplx * cplx -> cplx = "$1*$2"; |
| 23 | +fun / : cplx * cplx -> cplx = "$1/$2"; |
| 24 | +fun == : cplx * cplx -> bool = "$1==$2"; |
| 25 | +fun real: cplx -> double = "$1.real()"; |
| 26 | +fun imag: cplx -> double = "$1.imag()"; |
| 27 | +fun abs: cplx -> double = "$1.abs()"; |
| 28 | +fun arg: cplx -> double = "$1.arg()"; |
| 29 | +fun norm: cplx -> double = "$1.norm()"; |
| 30 | +fun conj: cplx -> double = "$1.conj()"; |
| 31 | + |
| 32 | +typedef polarbear = cplx; |
| 33 | +ctor polarbear: double * double = "::std::polar<double>($1,$2)"; |
| 34 | + |
| 35 | +fun str (x: cplx) => x.real.str + "+" + x.imag.str + "i"; |
| 36 | + |
| 37 | +// test |
| 38 | +var x = cplx (1.0,2.0); |
| 39 | +var y = polarbear (1.0,0.5); |
| 40 | +println$ (x+y).str; |
| 41 | +println$ (x == y).str; |
| 42 | +@ |
| 43 | +@h2 Type Classes |
| 44 | +Let us try an experiment: |
| 45 | +@tangle ex1 |
| 46 | +println$ (x,y); |
| 47 | +@ |
| 48 | + |
| 49 | +If you run it at this point without the rest of the tutorial, this happens: |
| 50 | +@pre |
| 51 | +CLIENT ERROR |
| 52 | +[flx_frontend/flx_typeclass.ml:752: E367] [Cannotmatch] Cannot instantiate virtual str<17781>[Nominal[] cplx] |
| 53 | +In /Users/skaller/felix/src/packages/core_type_constructors.fdoc: line 693, cols 4 to 59 |
| 54 | +692: instance[T] Str[T*T] { |
| 55 | +693: fun str (t1:T, t2:T) => "("+str t1 + ", " + str t2+")"; |
| 56 | + ******************************************************** |
| 57 | +694: } |
| 58 | +@ |
| 59 | +Its not very helpful. But here is a fix: |
| 60 | +@tangle ex1 |
| 61 | +instance Str[cplx] { |
| 62 | + fun str (x: cplx) => x.real.str + "+" + x.imag.str + "i"; |
| 63 | +} |
| 64 | +@ |
| 65 | +and now we get this: |
| 66 | +@pre |
| 67 | +(1+2i, 0.877583+0.479426i) |
| 68 | +@ |
| 69 | +To understand what's going on you need to see some of the |
| 70 | +Standard Library: |
| 71 | +@felix |
| 72 | +class Str [T] { |
| 73 | + virtual fun str: T -> string; |
| 74 | +} |
| 75 | +@ |
| 76 | +By instantiating the virtual function in an @{instance} the definition |
| 77 | +is available universally. |
| 78 | + |
| 79 | +@h1 Another type class |
| 80 | +Since the last type class was a bit easy here's a slightly harder one.. only |
| 81 | +slightly harder I promise! |
| 82 | +@felix |
| 83 | +// equality: technically, equivalence relation |
| 84 | +class Eq[t] { |
| 85 | + virtual fun == : t * t -> bool; |
| 86 | + virtual fun != (x:t,y:t):bool => not (x == y); |
| 87 | + |
| 88 | + axiom reflex(x:t): x == x; |
| 89 | + axiom sym(x:t, y:t): (x == y) == (y == x); |
| 90 | + axiom trans(x:t, y:t, z:t): x == y and y == z implies x == z; |
| 91 | + |
| 92 | + fun eq(x:t, y:t)=> x == y; |
| 93 | + fun ne(x:t, y:t)=> x != y; |
| 94 | + fun \ne(x:t, y:t)=> x != y; |
| 95 | + fun \neq(x:t, y:t)=> x != y; |
| 96 | +} |
| 97 | +@ |
| 98 | +This is a Felix <em>type class</em> . The design is modelled after Haskell. |
| 99 | +It has: |
| 100 | + |
| 101 | +<ol> |
| 102 | +<li> A name @{Eq} |
| 103 | +<li> A type parameter @{t} |
| 104 | +<li> An undefined virtual function for equality |
| 105 | +<li> An virtual function for inequality with a default definition |
| 106 | +<li> A set of @{axiom} which help to define the semantics |
| 107 | +<li> A collection of derived functions all of which are trivial renamings |
| 108 | +</ol> |
| 109 | + |
| 110 | +You have already seen the syntax for instantiating virtuals by |
| 111 | +setting the type variable @{t} to the type @{cplx}. The inquality |
| 112 | +can be defined as well but if not, as in this case, is derived |
| 113 | +from the euqliaty. |
| 114 | + |
| 115 | +The derived functions are available with the class also, but |
| 116 | +cannot be defined in an @{instance}. |
| 117 | + |
| 118 | +@h1 TeX symbols |
| 119 | +You may have notices in the @{Eq} type class that there is a |
| 120 | +function with the weird name @{\ne}. Which shown as $\eq$ in TeX. |
| 121 | + |
| 122 | + |
| 123 | + |
0 commit comments