On 27/08/2014, at 5:11 AM, Ryan Gonzalez wrote: > AHA! I had written: > > println string; > > instead of: > > println str; // str is the variable name
Yeah, sorry the diagnostic doesn't refer to the source of the error. I will have a look to see if I can fix that. Its very hard to do regression tests on error diagnostics because they have a tendency to change with small changes in the compiler, library, or source. An error catalogue would fix that but that's an absolutely massive job. Be warned that "str" is also a popular function, defined for almost all library types: 1.str 1.3.str etc etc. In fact it is worth seeing how this works now: warning .. lecture on Type Classes follows: in src/lib/std/flx_tclass.flx: class Str [T] { virtual fun str: T -> string; } class Repr [T with Str[T]] { virtual fun repr (t:T) : string => str t; } class Show [T] { inherit Str[T]; inherit Repr[T]; } We define three type classes. The first one, Str, is a class of types which support a str operation. The second, Repr, is for types which support str AND repr. The third one is used to make both available as we will see. The functions "str" and "repr" are based on Python "str" and "repr". str is for showing a value in the usual form. repr is a special one for showing it more like a Felix literal. Mainly, str on a string is the contents of the string, whereas repr has enclosing quotes and encodes special characters. As in Python. These classes define virtual functions which means they're declared like a template declaration, but not defined. To define them, like a C++ template definition, and in particular a specialisation we create an instance like this: instance Str[unit] { fun str (x:unit) => "()"; } This tells how to "str" the single value of type unit, the empty tuple (). You can now write: ().Str::str and it is the string "()". To save writing the full qualified name "Str::" we can do this: open Str[unit]; In fact, the library does this: open Show[unit]; so that repr works too. Note that the definition of repr defaults to str: here's the class definition again: class Repr [T with Str[T]] { virtual fun repr (t:T) : string => str t; } Now you see what the "with Str[T]" means: it is a constraint which says the type T has to have an instance for Str for the definition of the default repr to work. The "with" clause opens the Str class inside the Repr class. Now the magic: when you say: print 1; I'm afraid the library is cheating, because it has no idea how to print ANYTHING except for strings. So it rewrites your code like: print 1.str; Well actually that's the idea but .. here's the core code in the file src/lib/std/io/textio.flx: //$ Write data with conversion using Str::str. proc fprint[T with Str[T]] (s:output_text_file, x:T) { write (s, str x); }; You can see that to fprint something, you have to give it an output text file and some data which has a Str::str function defined on it. Then the fprint routine just calls write on the file and the string obtained by applying str function to your value. This is a great example of type class polymorphism at work. It's very similar to C++ templates with one major and vital difference: there is no dependent name lookup. That stuff is pure evil. Instead, you have to PASS the typeclass Str to the function fprint. Which you do with the "with Str[T]" clause. That makes Str open for T in the function so you can use str function on a value of type T. Here's how you can print your own data type: instance Str[mytype] { fun str (x:mytype) => "something_of_mytype"; } open Str[mytype]; Now you can just write var x : mytype = ... var s = s.str; println$ x; -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language