On 15/08/2012, at 4:03 AM, Dobes Vandermeer wrote: > > > The headtail() version returns a tuple, which you can pattern match on. > > that cannot work, because you cannot specify the type of "tail" > or of "head" given a tuple of type T. > > > I think it should be possible in general, but maybe something in missing in > Felix to support it?
No, its conceptually absurd, in some sense. you cannot apply an operation specific to some kind of structure (in this case tuple) without knowing that the thing is that kind. If the type is simply "not known at the moment" then you can attempt to apply the operation when the is known. At that point you will either succeed, or you will get a type error. With type classes you defer the operation from "compile" or binding time (phase one) to "link" or "instantiation" time (binding, phase two). Typematch feature in Felix defers things by simply failing to reduce until reduction is possible. Value pattern matches cannot do this, so what we do is "assume" we have a tuple by placing the type in a typeclass instance. That instance is only selected at instantiation time if the type variable actually resolves to a tuple, so the value match is type safe. If the type doesn't resolve to a tuple you get a "missing instance" error. So the type classes provide what in C++ is called "phase two lookup" and is associated with "dependent names" in templates, only the typeclass mechanism is good and the C++ one is rubbish (it isn't safe because there are no "concepts" to specify the "interface" required for the type when its a class) Usually in C++ this does NOT cause a problem, but it can pervert the semantics. > Ah, I see... how come this didn't cause all sorts of other problems? For > example, if you use that enum for something and try to match against the > missing parts of it? It did cause these problems. But Felix has the C++ approach: its only an error if you use it. It doesn't check for completeness or correctness for "features you don't actually use". So you only get a failure if you actually construct a test case. [Feiix is designed to do rapid prototyping, similar to dynamic language, without needing to do dynamic typing unless it is actually necessary] In fact there really was such a test case for mmap() which worked on Linux and failed on OSX. That's how I found out about it, and I had to remove the auto-generated code. This kind of thing CAN be supported, we just need to tell the compiler when to do it. In Haskell you can do this for "str" and "eq", you can tell the compiler to autogenerate those operations (only). Its a useful special case. Its not good enough (because it only works for str and eq) but better than hand rolling every str and eq on every complicated type if the compiler generated one would be good enough. By far the best way to "autogenerate" things is .. DONT! Put it in the library!! Do you understand the need for very high order typing and kinding systems? Its so we can move many of these auto-generated things out of the compiler and into the library. It's not a matter of type checking. That's the confusion many people have when they think the casting or whatever crud you need to do in OO is a good workaround. In higher order systems, we're not interested much in type *checking*. We're interested in using type and kind information to *automate* certain kinds of operations. The type system isn't there just to stop you making silly mistakes. Its there to *enable* automation. Overloading is a good example because its familiar. The parameter type of a function isn't declared and matched with the used argument type "just to check you use the right type". No, its actually used to **select** an appropriate function. The program wouldn't work at all in the absence of type information, because there's be no way to choose the right function. > You're using Java terminology I'm not familiar with. > > Ah, I thought you knew Java to some degree and thus your license to complain > about it. I do, to some degree. I actually got an HD in Java programming at Uni without every having written any Java. (Well not much anyhow). I studied Java as part of an ISO body as well. Yes, I did write some Java once (in the old days, playing with AWT 1.0 or something). But I don't know a lot of the nitty gritty details because they don't really matter for understanding the language system as a whole. > Actually I think stack overflows probably are not checked statically by > anyone. In a general (turing complete) language this hard to do. Some languages, however, cannot stack overflow, and most, if you have suitable restrictions (eg no recursion) also can't overflow (you can actually calculate the required stack size). In the old days many games were like that. > How do you code unions (sum types) in Java? > > That what the whole class system is for! A class is the union of its > subclasses. No it isn't. You see, that's the problem. Classes have two utterly distinct unrelated uses, one legitimate, and one completely fraudulent. Classes in OO language are supposed to provide abstraction. A derived class is supposed to be a subtype. Using a base as a union type with the derived classes as the components and RTTI for the discriminant is common practice but it is completely wrong. Unification (as in the sense of a union "unifying" distinct types) has nothing whatsoever to do with subtyping. It's used for that because the language doesn't provide a proper union. here a simple proof it doesn't work: union Result = | Square of double | Round of double WOOPS! You cannot do it with casts and objects because there are TWO cases but only one type. You can NOT use RTTI as a type constructor (Square, Round are type constructors). It doesn't work. C++ BOOST variant made this stupid mistake too. Heck, so did I, until I learned some theory (and a real language, in my case Ocaml). This may sound trivial but it is not. It confuses the heck out of OO programmers that they have to use classes/object for two distinct kinds of things, only they don't actually recognise it. Let me say again: a SUM of type is NOTHING AT ALL TO DO WITH SUBTYPING. NOTHING. ZERO. UNRELATED COMPLETELY. Sum types add ANY unrelated types together to make a single type. Subtyping is nothing more than a subset of the values of a type. Inheritance is typically designed for subtyping NOT unification. [In Ocaml, its much better: subtyping is structural not nominal, so you do not need to "derive" subtypes as you must do in Java and C++] > > They don't have a match statement, instead of you have to define methods on > the superclass that do the work. This is an area where Java starts to break > down, No, its an area where ALL OBJECT ORIENTATION breaks down. Its not a problem in Java as such. Its a problem with the whole idea of Object Orientation. The bottom line is as I said before: OO does not work. It cannot model interesting concepts. It can only model very boring simple concepts where a type is characterised entirely by properties. (property --> method). > the lack of match. Scala addresses this problem, which is nice, although > Scala has other problems that are quite severe. Like have to perform black > magic to make your own collection class. Really? Didn't know that. -1 for Scala :) > A trivial example: in physics you know if your formula is likely to be > correct, because you can apply dimensional analysis. Any compiler with a good type system can do this. It can be done in Haskell and in Ocaml. Not sure about Felix, but it will. in Felix it would loook like something like: typedef dimension = Length * Energy * Temperatuire * MagneticFlux ... where each of those standard 7 SI units could be 0, 1, 2, ... -1, -2, -3 ... Dimensional correctness is then just a matter of defining operations which say add double value AND add the types. Adding the types is a constraint that the types are equal. Multiplication adds the integer values of the types (metres * metres = metres ^ 2). So the analysis is basically a logarithmic calculation chained together with the value calculation (with the compiler doing the type calculation). This is real easy to do in C++ using templates because you can have integer arguments to templates. Felix should be able to do it too (but can't at the moment because sum types can't be added). In other words .. the compiler does not need to have this built in. It can be done just with user library code. > The behavior tree is hetergeneous, though ... so it would be a pain to do in > Felix compared to C++. In C++ I would make a common base class with virtual > methods. It is true Felix cannot do C++ virtual function dispatch. It used to but it was a nightmare to maintain and not of much use so I took it out. It would be good to put back in. > > If you think current games are using good technology and achieving > good results ... well you haven't played very many games. > > I haven't just played many games I have programmed them. Maybe you're the > one who is out of touch. Not at all. I've played a lot of games and most of them are utter rubbish. I also ran a game programming company at one time. I mean, the game "engines" are so completely and utterly primitive the games aren't worth playing. The interfaces are so lame they constrain game play so badly that you end up fighting the game programmer instead of the NPCs :) Games have got more reliable, and there's no doubt graphics and motion have improved a lot (although I'm more interested in games for people over 14). But the AI? Strategy? Are you kidding? Most games can't even do basic routing. Heck, that's so well understood many people have a GPS in their car that can do that. My yacht navigation computer can do it (though not very well). Routing is a hard problem, but thats no excuse for the utterly lame routing algorithms used in most games. Why is that? because the programmers spend most of their time either doing pretty graphics (instead of working on the game logic) or finding bugs, they don't have any time to actually work on the game engine. My challenge: show me one good strategy game. I'll go out and buy it. It has to be an actual strategy game! Not small unit tactics. It has to require strategic planning. There are quite a few "so called strategy games" out there. Some are simply not strategy games at all. Some actually are strategy games but they involve fighting some really lame strategic model and one soon figures out how to break it. Until it stopped working I played Europa Universalis. At least that was hard, and it had a reasonably good strategic model (but unfortunately the trading model sucked big time). I think that's the best strategy game I ever played (solo). -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language