Bernstein basis polynomials: Difference between revisions

→‎{{header|ATS}}: More pedagogical commentary. Also, I modularized the polynomial-printing code, demonstrating more aspects of the type system.
(Added more explanation of the type-safety design: why what C/Pascal/C++/etc. do is inadequate.)
(→‎{{header|ATS}}: More pedagogical commentary. Also, I modularized the polynomial-printing code, demonstrating more aspects of the type system.)
Line 572:
(* We will try to achieve the type-safety of distinguishing between
monomial and Bernstein bases at compile time, but without overhead
at runtime. (As muchSuch type-safety ascan webe achievepartly hereachieved canin bemany done inother
many other languages simply by giving the types different names but the same
the same fields. But then you cannot easily have typeTYPE-safeSAFE subprograms that
subprograms that work on EITHER type. Perhaps youYou could dohave itthat with a type hierarchy, but
athen, type hierarchytypically, but then you start getting runtime overhead.) *)from runtime
polymorphism. You could do it by nesting record types within record
types, but then you start needing the overhead of pointers to the
different nested types. Furthermore, these approaches are all
essentially WORKAROUNDS, rather than direct solutions to the
problem, which is "how to distinguish between a tuple representing
coefficients in ONE basis from the exact same kind of tuple
representing coefficients in A DIFFERENT basis, while also treating
both as coefficients in SOME basis, such as for addition or scalar
multiplication". Here we do that by attaching an object to the
tuple AT TYPECHECKING TIME that is entirely left out after
typechecking is complete.) *)
tkindef monoknd = "rosettacode_monomial_poly"
tkindef bernknd = "rosettacode_bernstein_poly"
Line 601 ⟶ 612:
mono2bern_degree2 with Bernstein coefficients (instead of monomial
coefficients) as the argument, then, AT COMPILE TIME, you get
messagemessages similar to these:
 
/some_path/bernstein_poly_task.dats: 1051(line=32, offs=31) -- 1052(line=32, offs=32): warning(3): the constraint [S2Eeqeq(S2Eextkind(rosettacode_bernstein_poly); S2Eextkind(rosettacode_monomial_poly))] cannot be translated into a form accepted by the constraint solver.
Line 675 ⟶ 686:
end
 
(* Let us make it easy to print out coefficients. *)Note that
print_poly_degree2 operates TYPE-SAFELY on ANY object of type
"poly", without regard to whether it represents monomial
coefficients or Bernstein coefficients. In C we might do such a
thing by casting a pointer of one type to a pointer of another
type, but that is not a TYPE-SAFE operation. *)
fn {coefknd : tkind}
print_poly_degree2 {polyknd : tkind}
print_mono_degree2 (coefs : poly_degree2 (monoknd, coefknd))
(coefs : poly_degree2 (polyknd, coefknd))
: void =
let
Line 683 ⟶ 700:
macdef outf = stdout_ref
in
fprint_val<string> (outf, "mono (");
fprint_val<g0float coefknd> (outf, a0);
fprint_val<string> (outf, ", ");
Line 693 ⟶ 710:
 
fn {coefknd : tkind}
print_poly_degree3 {polyknd : tkind}
print_bern_degree2 (coefs : poly_degree2 (bernknd, coefknd))
print_mono_degree3 (coefs : poly_degree3 (monokndpolyknd, coefknd))
: void =
let
val+ @(_ | b0, b1, b2) = coefs
macdef outf = stdout_ref
in
fprint_val<string> (outf, "bern (");
fprint_val<g0float coefknd> (outf, b0);
fprint_val<string> (outf, ", ");
fprint_val<g0float coefknd> (outf, b1);
fprint_val<string> (outf, ", ");
fprint_val<g0float coefknd> (outf, b2);
fprint_val<string> (outf, ")")
end
 
fn {coefknd : tkind}
print_mono_degree3 (coefs : poly_degree3 (monoknd, coefknd))
: void =
let
Line 715 ⟶ 717:
macdef outf = stdout_ref
in
fprint_val<string> (outf, "mono (");
fprint_val<g0float coefknd> (outf, a0);
fprint_val<string> (outf, ", ");
Line 724 ⟶ 726:
fprint_val<g0float coefknd> (outf, a3);
fprint_val<string> (outf, ")")
end
 
fn {coefknd : tkind}
print_mono_degree2 (coefs : poly_degree2 (monoknd, coefknd))
: void =
begin
fprint_val<g0float coefkndstring> (outfstdout_ref, b0"mono ");
print_poly_degree2 (coefs)
end
 
fn {coefknd : tkind}
print_bern_degree2 (coefs : poly_degree2 (bernknd, coefknd))
: void =
begin
fprint_val<string> (outfstdout_ref, "bern (");
print_poly_degree2 (coefs)
end
 
fn {coefknd : tkind}
print_mono_degree3 (coefs : poly_degree3 (monoknd, coefknd))
: void =
begin
fprint_val<string> (outfstdout_ref, ",mono ");
print_poly_degree3 (coefs)
end
 
Line 729 ⟶ 755:
print_bern_degree3 (coefs : poly_degree3 (bernknd, coefknd))
: void =
letbegin
fprint_val<g0float coefkndstring> (outfstdout_ref, b1"bern ");
val+ @(_ | b0, b1, b2, b3) = coefs
print_poly_degree3 (coefs)
macdef outf = stdout_ref
in
fprint_val<string> (outf, "bern (");
fprint_val<g0float coefknd> (outf, b0);
fprint_val<string> (outf, ", ");
fprint_val<g0float coefknd> (outf, b1);
fprint_val<string> (outf, ", ");
fprint_val<g0float coefknd> (outf, b2);
fprint_val<string> (outf, ", ");
fprint_val<g0float coefknd> (outf, b3);
fprint_val<string> (outf, ")")
end
 
1,448

edits