Python from Wise Guy's Viewpoint

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Matthias Blume

    Re: Python from Wise Guy's Viewpoint

    Matthew Danish <mdanish@andrew .cmu.edu> writes:
    [color=blue]
    > On Mon, Oct 27, 2003 at 10:08:15PM +0100, Joachim Durchholz wrote:[color=green]
    > > Matthew Danish wrote:
    > >[color=darkred]
    > > >On Mon, Oct 27, 2003 at 07:00:01PM +0100, Andreas Rossberg wrote:
    > > >
    > > >>Pascal Costanza wrote:
    > > >>
    > > >>>Can you show me an example of a program that does't make sense anymore
    > > >>>when you strip off the static type information?
    > > >>
    > > >>Here is a very trivial example, in SML:
    > > >>
    > > >> 20 * 30
    > > >>
    > > >>Multiplicatio n, as well as literals, are overloaded. Depending on
    > > >>whether you type this expression as Int8.int (8-bit integers) or
    > > >>IntInf.int (infinite precision integer) the result is either 600 or an
    > > >>overflow exception.
    > > >
    > > >May I point out that the correct answer is 600, not overflow?[/color]
    > >
    > > No, the correct answer isn't 600 in all cases.
    > > If it's infinite-precision arithmetic, the correct answer is indeed 600.
    > > If it's 8-bit arithmetic with overflow, there is no correct answer.
    > > If it's 8-bit arithmetic with wrap-around, the correct answer is 88.
    > > If it's 8-bit arithmetic with saturation, the correct answer is 255.
    > > (The result happens to be independent of whether the arithmetic is
    > > signed or unsigned.)[/color]
    >
    > What is this stuff? I am talking about integers here! You know, the
    > infinite set with the same cardinality as natural numbers.[/color]

    I didn't see you say that. If you write 20 * 30 in SML, then you are
    *not* talking about the infinite set of integers but rather about a set
    [-2^N..2^N-1] where N is something like 31 or 32. If you had written

    20 * 30 : IntInf.int

    or something like that, then you would have talked about the infinite
    set of integeres, and you would have gotten your "correct" result of
    600. [I still have no idea why that is more "correct" than, say, 18.
    That's the result in Z_{97}.]
    [color=blue]
    > Lisp gets exact rational arithmetic right, why don't ML or Haskell?
    > Clever compilers like CMUCL can even emit efficient code when it can
    > figure out the specific types. Surely a statically typed language would
    > find this even easier![/color]

    Sure, it is definitely not any harder than it is in Lisp. The problem
    is that for many algorithms people want to be sure that the compiler
    represents their values in machine words. Infinite precision is
    needed sometimes, but in the majority of cases it is overkill. If you
    need infinite precision, specify the type (IntInf.int in SML's case).
    A clever compiler might optimize that like a Lisp compiler does. In
    most other cases, why take any chances?

    Matthias

    Comment

    • Matthias Blume

      Re: Python from Wise Guy's Viewpoint

      Matthew Danish <mdanish@andrew .cmu.edu> writes:
      [color=blue]
      > On Tue, Oct 28, 2003 at 11:20:45AM +0100, ketil+news@ii.u ib.no wrote:[color=green]
      > > Matthew Danish <mdanish@andrew .cmu.edu> writes:[color=darkred]
      > > > What is this stuff? I am talking about integers here![/color]
      > >
      > > But the SML program isn't. Or it may be, and maybe not. So it's
      > > ambigous without type information.
      > >[color=darkred]
      > > > Why can't the implementation figure out how to represent them most
      > > > efficiently?[/color]
      > >
      > > Because it needs a type annotation or inference to decide that the
      > > numbers are indeed integers, and not a different set with different
      > > arithmetic properties.[/color]
      >
      > 1 is an integer. Simple type inference. In Lisp, it's also a fixnum,
      > it's also an (unsigned-byte 23), it's also an (integer 1 (2)), etc.
      >[color=green][color=darkred]
      > > > Lisp gets exact rational arithmetic right, why don't ML or Haskell?[/color]
      > >
      > > Could you point to a case where they don't? I don't understand your
      > > criticism at all. Is the ability to do modulo arithmetic "wrong"?[/color]
      >
      > - fun fact 0 = 1 | fact n = n * fact (n - 1);
      > val fact = fn : int -> int
      > - fact 10;
      > val it = 3628800 : int
      > - fact 15;
      > val it = 1307674368000 : int (* ideally *)[/color]

      $ sml
      Standard ML of New Jersey v110.43.3 [FLINT v1.5], September 26, 2003
      - fun fact 0 = 1 : IntInf.int
      = | fact n = n * fact (n - 1);
      [autoloading]
      [autoloading done]
      val fact = fn : IntInf.int -> IntInf.int
      - fact 15;
      val it = 1307674368000 : IntInf.int
      -
      [color=blue]
      > - 1 * 1.0;
      > val it = 1.0 : float (* ideally *)[/color]

      That's not "ideal" at all, to me. I find the automatic conversions in
      C a paint in the b*tt because it is not obvious at all where they
      happen in a given expression. How hard is it to write

      real 1 * 1.0

      thereby making things explicit, unambiguous, and non-surprising?

      Matthias

      Comment

      • John Atwood

        Re: Python from Wise Guy's Viewpoint

        Matthew Danish <mdanish@andrew .cmu.edu> wrote:[color=blue]
        >On Sat, Oct 25, 2003 at 12:37:38AM +0000, John Atwood wrote:[color=green]
        >> Pascal Costanza <costanza@web.d e> wrote:
        >>[color=darkred]
        >> >- when a test case gives me an exception, I can inspect the runtime
        >> >environment and analyze how far the test case got, what it already
        >> >successfully did, what is missing, and maybe even why it is missing.
        >> >With a statically typed language, I wouldn't be able to get that far.
        >> >
        >> >Furthermore, when I am still in the exceptional situation, I can change
        >> >variable settings, define a function on the fly, return some value from
        >> >a yet undefined method by hand to see if it can make the rest of the
        >> >code work, and so on.[/color]
        >>
        >> That's because you're in an interpreted environemt, not because you're
        >> using a dynamically typed language. Interpreters for statically typed
        >> languages allow the same.[/color]
        >
        >Wrong on all counts.
        >
        >* Most Common Lisp environments compile to native code, even when
        > working interactively.
        > SBCL, for example, has no interpreter whatsoever. The interpreter is
        > simulated by calling the compiler and evaluating the resulting
        > function immediately.[/color]

        If the code is executed in the environment, and one can execute
        arbitrary snippets of code, it's an interpreted environment,
        regardless of whether the code executed is native, bytecode,
        or other.
        [color=blue]
        >* There exists statically typed language implementations which do the
        > same (SML/NJ)[/color]

        Yes, these are among those I have in mind when I say "Interprete rs for
        statically typed languages allow the same."
        [color=blue]
        >* The behavior of redefinition in a statically typed environment
        > is far different from the behavior in a dynamically typed environment.
        > For one thing, generativity of names kicks in, which makes it
        > basically impossible to redefine types and functions without
        > recompiling all uses (and thus restarting your program), in a static
        > environment.[/color]

        Yes, and that's a good thing. It prevents the program form getting in an
        unreachable/inconsistent state, and secondly, in an FP, especially a pure
        FP, with explicit state, one need not run the program from the start to
        test whatever code is of interest at the moment, because the state can be
        created via test cases.


        John

        Comment

        • Don Geddis

          Re: Python from Wise Guy's Viewpoint

          Marcin 'Qrczak' Kowalczyk <qrczak@knm.org .pl> writes:[color=blue]
          > You make some array of doubles, set a[i] = exp(i) (a double) and it works.
          > Then you set a[i] = 2*i (an integer) and it still works, because the
          > integer has been converted to double during assignment. An integer can be
          > used in place of a double with the same value.[/color]

          Surely in a "proper" staticly typed language, you can't assign an integer
          to a variable declared (floating point) double. Shouldn't that be a type
          error? (Unless you do an explicit cast, of course, but then the programmer
          made the decision, not the language.)
          [color=blue]
          > Now in a dynamically typed language the analogous code would set some
          > array elements to integers without conversion. If division on them means
          > a different thing, an integer can no longer be used in place of a floating
          > point number with the same value. And division is the only operation whith
          > breaks this.[/color]

          Why would division on integers mean something different than division on
          (floating point) doubles?
          [color=blue]
          > Dynamically typed languages shouldn't use / for both real and truncating
          > division. For statically typed languages it's only a matter of taste (I
          > prefer to use different symbols), but for dynamically typed languages it's
          > important to prevent bugs.[/color]

          In Lisp, "/" always means the same thing. It's never a truncating operation.

          This doesn't seem to be related to static vs. dynamic typing.

          -- Don
          _______________ _______________ _______________ _______________ _______________ ____
          Don Geddis http://don.geddis.org/ don@geddis.org
          Football combines two of the worst things about American life.
          It is violence punctuated by committee meetings.
          -- George Will

          Comment

          • Don Geddis

            Re: Python from Wise Guy's Viewpoint

            Andreas Rossberg <rossberg@ps.un i-sb.de> writes:[color=blue]
            > I should note in this context is that static types usually express different
            > things than dynamic ones, especially when it comes to number types. In Lisp,
            > the runtime tag of a number will usually describe the representation of the
            > number. This may well change between operations. But static typing, at least
            > in high-level languages, is about semantics. If I choose a certain integer
            > type I do so because it has the desired domain, which I want to have checked
            > - I'm not at all interested in its representation.[/color]

            Types don't have to be disjoint. In Lisp, if a data object is a FIXNUM,
            at the same time it's also a NUMBER. And perhaps an (INTEGER 0 16) too.

            Yes, at least one of the types defines the representation. But there are
            semantic types as well.

            As to "change between operations": it doesn't matter what your type system is.
            Any function call has the potential to "change types". It would be a silly
            system that requires the (type) domain and range of every function to always
            be identical.
            [color=blue]
            > In fact, values of IntInf are likely to have multiple representations
            > depending on their size, but the type is invariant, abstracting away from
            > such low-level representation details.[/color]

            And Lisp's NUMBER type also has multiple representations . And the SQRT
            function takes a NUMBER and returns a NUMBER. But also, at the same time,
            it takes INTEGERs and returns FLOATs, and takes negative INTEGERs and returns
            COMPLEX NUMBERs. Semantics and representation, all at the same time!
            [color=blue]
            > Actually, I think dynamic typing should abstract from this as well, but
            > unfortunately this does not seem to happen.[/color]

            But it does.
            [color=blue]
            > Because the designers decided (rightly so, IMHO) that it is best to avoid
            > implicit conversions, since they might introduce subtle bugs and does not
            > coexist well with type inference.[/color]

            Sounds like a tradeoff. Perhaps, for some programmers, the freedom you get
            with implicit type conversions is more valuable than the benefits of type
            inference?

            -- Don
            _______________ _______________ _______________ _______________ _______________ ____
            Don Geddis http://don.geddis.org/ don@geddis.org

            Comment

            • Matthew Danish

              Re: Python from Wise Guy's Viewpoint

              On Tue, Oct 28, 2003 at 06:52:08PM +0000, John Atwood wrote:[color=blue]
              > Matthew Danish <mdanish@andrew .cmu.edu> wrote:[color=green]
              > >* Most Common Lisp environments compile to native code, even when
              > > working interactively.
              > > SBCL, for example, has no interpreter whatsoever. The interpreter is
              > > simulated by calling the compiler and evaluating the resulting
              > > function immediately.[/color]
              >
              > If the code is executed in the environment, and one can execute
              > arbitrary snippets of code, it's an interpreted environment,
              > regardless of whether the code executed is native, bytecode,
              > or other.[/color]

              So long as you are clear on the meaning. For most people, calling
              something an interpreted environment implies lack of compiler.
              [color=blue][color=green]
              > >* The behavior of redefinition in a statically typed environment
              > > is far different from the behavior in a dynamically typed environment.
              > > For one thing, generativity of names kicks in, which makes it
              > > basically impossible to redefine types and functions without
              > > recompiling all uses (and thus restarting your program), in a static
              > > environment.[/color]
              >
              > Yes, and that's a good thing. It prevents the program form getting in an
              > unreachable/inconsistent state, and secondly, in an FP, especially a pure
              > FP, with explicit state, one need not run the program from the start to
              > test whatever code is of interest at the moment, because the state can be
              > created via test cases.[/color]

              And it also gets in the way of the flexibility traditionally associated
              with dynamically typed languages. It gets in the way of development and
              debugging as well. And as for pure FP, can you recreate network
              connection state at will? So that the other end doesn't even know
              something went wrong (besides the delay)?

              --
              ; Matthew Danish <mdanish@andrew .cmu.edu>
              ; OpenPGP public key: C24B6010 on keyring.debian. org
              ; Signed or encrypted mail welcome.
              ; "There is no dark side of the moon really; matter of fact, it's all dark."

              Comment

              • Marcin 'Qrczak' Kowalczyk

                Re: Python from Wise Guy's Viewpoint

                On Tue, 28 Oct 2003 08:57:34 -0800, Don Geddis wrote:
                [color=blue]
                > Why would division on integers mean something different than division on
                > (floating point) doubles?[/color]

                Because C did it this way and many languages are copying its conventions.
                And C did it because it used / for integer division before it had floating
                point types.

                I was responding to "Something that annoys me about many statically-typed
                languages is the insistence that arithmetic operations should return the
                same type as the operands. 2 / 4 is 1/2, not 0."

                While it is true that many statically typed languages do that, it's not
                a consequence of static typing (others don't). The only fault of static
                typing here is that it makes this choice relatively harmless, compared to
                dynamically typed languages where it's a serious problem if this choice
                is made.

                I was going to respond "making 2/4 equal to 0 is unrelated to static or
                dynamic typing", but it *is* related, only in a subtle way.

                --
                __("< Marcin Kowalczyk
                \__/ qrczak@knm.org. pl
                ^^ http://qrnik.knm.org.pl/~qrczak/

                Comment

                • Pascal Costanza

                  Re: Python from Wise Guy's Viewpoint

                  Matthias Blume wrote:[color=blue]
                  > Pascal Costanza <costanza@web.d e> writes:
                  >
                  >[color=green]
                  >>Can you give a better example of a program that would render
                  >>meaningless without type annotations?[/color]
                  >
                  >
                  > fun f A = "A"
                  > | f B = "B"
                  >[/color]

                  I don't find this convincing. This is similar to the 20 * 30 example.

                  The resolution in both cases would be to define a default meaning if no
                  explicit type annotation exists. Done.

                  These examples don't allow me to write one single meaningful program
                  more than in a dynamically typed language.

                  My claim that dynamically typed languages have more expressive power
                  means that they allow you to write more programs that show useful
                  behavior at runtime. The strongest example I have are programs that
                  allow arbitrary changes to the definitions that are embedded inside of
                  them. That's the essence of metacircularity (runtime metaobject
                  protocols, etc). You cannot statically type check such programs by
                  definition.

                  I think that Neelakantan has better examples for programs that are
                  possible to write with a statically typed language, but not with
                  dynamically typed ones. (Not 100% sure yet, though.)


                  Pascal

                  Comment

                  • Pascal Costanza

                    Re: Python from Wise Guy's Viewpoint

                    Stephen J. Bevan wrote:
                    [color=blue]
                    > Pascal Costanza <costanza@web.d e> writes:
                    >[color=green]
                    >>Fergus Henderson wrote:
                    >>
                    >>[color=darkred]
                    >>>>Dynamic typing works better with XP than static typing because with
                    >>>>dynamic typing you can write unit tests without having the need to
                    >>>>immediate ly write appropriate target code.
                    >>>
                    >>>That one seems to have been pretty thoroughly debunked by other
                    >>>responses
                    >>>in this thread. A static type system won't stop you writing unit tests.
                    >>>And if you want to actually run the unit tests, then you are going to
                    >>>need appropriate target code, regardless of whether the system is
                    >>>statically or dynamically typed.[/color]
                    >>
                    >>Not if I only want to check whether the first ten tests work, and
                    >>don't care about the remaining ones.[/color]
                    >
                    >
                    > Perhaps I'm just a low tech kind of guy but if I just want to run the
                    > first ten then I comment out the rest. Even without a fancy IDE that
                    > only take a few key presses.[/color]

                    ....and it requires you to go to all the places where they are defined.

                    Yes, I know the answer: "But they should be all in one place." No, they
                    shouldn't need to be all in one place. For example, I might want to
                    place test code close to the definitions that they test. Or I might want
                    to organize them according to some other criteria.

                    No, it's not hard to find them all, then. I can use grep or my IDE to
                    find them. But that's still more work than just commenting them out. If
                    I seldomly need to find all test cases, I can trade locality of all test
                    cases for some other possible advantages.

                    Ah, another example: What if my test code is actually produced by some
                    macro, or some other code generation facility?


                    Pascal

                    Comment

                    • Matthias Blume

                      Re: Python from Wise Guy's Viewpoint

                      Pascal Costanza <costanza@web.d e> writes:
                      [color=blue]
                      > Matthias Blume wrote:[color=green]
                      > > Pascal Costanza <costanza@web.d e> writes:
                      > >[color=darkred]
                      > >>Can you give a better example of a program that would render
                      > >>meaningless without type annotations?[/color]
                      > > fun f A = "A"[/color]
                      >[color=green]
                      > > | f B = "B"
                      > >[/color]
                      >
                      > I don't find this convincing. This is similar to the 20 * 30 example.
                      >
                      > The resolution in both cases would be to define a default meaning if
                      > no explicit type annotation exists. Done.[/color]

                      Of course, you can always define a default meaning for the case that
                      no explicit (type) information is available. But what you are doing
                      is essentially providing such information: no explicit type annotation
                      amounts to having an implicit annotation.

                      By the way, this is how, e.g., SML does it anyway: If you write just
                      20*30 and nothing else is known, then the type is resolved to be
                      Int.int.

                      This does not invalidate the claim that you know the semantics of the
                      phrase only if you know the type. It just so happens that you always
                      know the type.
                      [color=blue]
                      > I think that Neelakantan has better examples for programs that are
                      > possible to write with a statically typed language, but not with
                      > dynamically typed ones. (Not 100% sure yet, though.)[/color]

                      There are no such programs, obviously. You can always translate a
                      statically typed program into a dynamically typed one (and vice
                      versa).

                      The advantage (as far as I am concerned) of the statically typed
                      program is in the guarantees that it provides: If I write

                      fun foo x = ...

                      and x is declared or inferred to be of type t, then I never again have
                      to worry about what happens should someone pass a non-t to foo
                      because that simply cannot happen. This all by itself is useful, but
                      it gets even more useful if t is an abstract type so that I have full
                      control over how and where t values are generated.

                      This sort of thing is most useful when designing libraries because in
                      this case you don't know yet (who will call foo and how (and you might
                      in fact never know). But you do know that whoever it is and however he
                      does it, he must pass a value of type t.

                      Matthias

                      Comment

                      • Pascal Costanza

                        Re: Python from Wise Guy's Viewpoint

                        Andreas Rossberg wrote:
                        [color=blue]
                        > The design of a type system is by no means canonical. In fact, it is
                        > based on set of pragmatic decisions and trade-offs. Idealized, you start
                        > with the trivial type system, which has only one type. Then you refine
                        > it incrementally by distinguishing certain classes of values through
                        > introduction of new types and typing rules. Introduction of typing rules
                        > is based on the following criteria:
                        >
                        > - Do they catch a lot of errors?
                        > - Are these errors serious?
                        > - Are they hard to localize otherwise?
                        > - Does the refinement rule out useful constructions?
                        > - Are such constructions common?
                        > - Are they expressible by other means?
                        > - Are the rules intuitive?
                        > - Do they interact nicely with other rules?
                        >
                        > And probably more. There are never any definite answers to any of these
                        > questions. The trade-off depends on many factors, such as the problem
                        > domain the language is used for. Usually the line is drawn based on
                        > experience with other languages and known problem domains. In the case
                        > of arbitrary recursive types, experience with languages that allowed
                        > them has clearly shown that it caused much more grief than joy.[/color]

                        Hmm, could a kind of "meta type system protocol" be feasible? I.e., a
                        language environment in which you could tweak the type system to your
                        concrete needs, without having to change the language completely?


                        Pascal

                        Comment

                        • Pascal Costanza

                          Re: Python from Wise Guy's Viewpoint

                          Matthias Blume wrote:
                          [color=blue]
                          > The problem
                          > is that for many algorithms people want to be sure that the compiler
                          > represents their values in machine words. Infinite precision is
                          > needed sometimes, but in the majority of cases it is overkill. If you
                          > need infinite precision, specify the type (IntInf.int in SML's case).
                          > A clever compiler might optimize that like a Lisp compiler does. In
                          > most other cases, why take any chances?[/color]

                          I disagree strongly here. I am convinced that in most algorithms,
                          machine words don't matter at all. Have you ever seen in books on
                          algorithms that they actually _need_ to restrict them to values that are
                          representable in machine word sizes?

                          "Here is a proof for the correctness of the Quicksort algorithm, but
                          only for arrays with a maximum length of 65535." Ha! Nonsense! ;-)


                          Computers are fast enough and have enough memory nowadays. You are
                          talking about micro efficiency. That's not interesting anymore.


                          (but I have no problems if we agree to disagree here. we both don't have
                          the necessary empirical data to back our claims)

                          Pascal

                          Comment

                          • Pascal Costanza

                            Re: Python from Wise Guy's Viewpoint

                            John Atwood wrote:
                            [color=blue][color=green]
                            >>* The behavior of redefinition in a statically typed environment
                            >> is far different from the behavior in a dynamically typed environment.
                            >> For one thing, generativity of names kicks in, which makes it
                            >> basically impossible to redefine types and functions without
                            >> recompiling all uses (and thus restarting your program), in a static
                            >> environment.[/color]
                            >
                            >
                            > Yes, and that's a good thing. It prevents the program form getting in an
                            > unreachable/inconsistent state,[/color]

                            Oh dear, that argument again.

                            No, to repeat this for the nth time, that's not _generally_ a good
                            thing. It also prevents the program from getting in a certain class of
                            states that would still be reachable/consistent. So, in some situations
                            it might be a _bad_ thing.


                            Pascal

                            Comment

                            • Matthias Blume

                              Re: Python from Wise Guy's Viewpoint

                              Pascal Costanza <costanza@web.d e> writes:
                              [color=blue]
                              > Computers are fast enough and have enough memory nowadays. You are
                              > talking about micro efficiency. That's not interesting anymore.[/color]

                              I have worked on projects where people worried about *every cycle*.
                              (Most of the time I agree with you, though. Still, using infinite
                              precision by default is, IMO, a mistake. Having it around and at your
                              fingertips, though, is nice. That's why I added the long-missing
                              compiler support for IntInf to SML/NJ recently.)
                              [color=blue]
                              > (but I have no problems if we agree to disagree here.[/color]

                              Good.
                              [color=blue]
                              > we both don't have the necessary empirical data to back our claims)[/color]

                              Speak for yourself.

                              Matthias

                              Comment

                              • Pascal Costanza

                                Re: Python from Wise Guy's Viewpoint

                                Matthias Blume wrote:
                                [color=blue]
                                > Pascal Costanza <costanza@web.d e> writes:[/color]
                                [color=blue][color=green]
                                >>I think that Neelakantan has better examples for programs that are
                                >>possible to write with a statically typed language, but not with
                                >>dynamically typed ones. (Not 100% sure yet, though.)[/color]
                                >
                                > There are no such programs, obviously. You can always translate a
                                > statically typed program into a dynamically typed one (and vice
                                > versa).[/color]

                                No, for christ's sake! There are dynamically typed programs that you
                                cannot translate into statically typed ones!

                                As soon as you add full-fledged runtime metaprogramming to a language,
                                and write a program that uses it, you cannot statically type check this
                                anymore, by definition, because you cannot statically determine anymore
                                in what ways such a program would change during its lifetime!

                                And don't tell me that "in 99% of all cases, you don't need this". This
                                just isn't true. And even if it were true, it wouldn't matter!

                                If there would only be _one_ useful program on earth that someone cared
                                about that would make use of runtime metaprogramming , this would make my
                                statement true that static typing decreases expressive power in possibly
                                serious ways. And there are definitely lots of them out there!
                                [color=blue]
                                > The advantage (as far as I am concerned) of the statically typed
                                > program is in the guarantees that it provides: If I write
                                >
                                > fun foo x = ...
                                >
                                > and x is declared or inferred to be of type t, then I never again have
                                > to worry about what happens should someone pass a non-t to foo
                                > because that simply cannot happen. This all by itself is useful, but
                                > it gets even more useful if t is an abstract type so that I have full
                                > control over how and where t values are generated.
                                >
                                > This sort of thing is most useful when designing libraries because in
                                > this case you don't know yet (who will call foo and how (and you might
                                > in fact never know). But you do know that whoever it is and however he
                                > does it, he must pass a value of type t.[/color]

                                Yes, these things are all obvious. But these are not examples for an
                                increase of expressive power! These are only examples of _restricting_
                                the set of potentially useful programs! How hard is this to understand?

                                You _want_ this restriction. Why don't you _admit_ that it is a restriction?


                                Pascal

                                Comment

                                Working...