Python from Wise Guy's Viewpoint

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jacques Garrigue

    #421
    Re: Python from Wise Guy's Viewpoint

    Pascal Costanza <costanza@web.d e> writes:
    [color=blue]
    > Matthias Blume wrote:
    >[color=green][color=darkred]
    > >>No, it's not. There's a class of programs that exhibit a certain
    > >>behavior at runtime that you cannot write in a statically typed
    > >>language _directly in the language itself_.[/color]
    > >
    > > This is simply not true. See above.[/color]
    >
    > OK, let's try to distill this to some simple questions.
    >
    > Assume you have a compiler ML->CL that translates an arbitrary ML
    > program with a main function into Common Lisp. The main function is a
    > distinguished function that starts the program (similar to main in C).
    > The result is a Common Lisp program that behaves exactly like its ML
    > counterpart, including the fact that it doesn't throw any type errors at
    > runtime.
    >
    > Assume furthermore that ML->CL retains the explicit type annotations in
    > the result of the translation in the form of comments, so that another
    > compiler CL->ML can fully reconstruct the original ML program without
    > manual help.
    >
    > Now we can modify the result of ML->CL for any ML program as follows. We
    > add a new function that is defined as follows:
    >
    > (defun new-main ()
    > (loop (print (eval (read)))))
    >
    > (We assume that NEW-MAIN is a name that isn't defined in the rest of the
    > original program. Otherwise, it's easy to automatically generate a
    > different unique name.)
    >
    > Note that we haven't written an interpreter/compiler by ourselves here,
    > we just use what the language offers by default.
    >
    > Furthermore, we add the following to the program: We write a function
    > RUN (again a unique name) that spawns two threads. The first thread
    > starts the original main function, the second thread opens a console
    > window and starts NEW-MAIN.
    >
    > Now, RUN is a function that executes the original ML program (as
    > translated by ML->CL, with the same semantics, including the fact that
    > it doesn't throw any runtime type errors in its form as generated by
    > ML->CL), but furthermore executes a read-eval-print-loop that allows
    > modification of the internals of that original program in arbitrary
    > ways. For example, the console allows you to use DEFUN to redefine an
    > arbitrary function of the original program that runs in the first
    > thread, so that the original definition is not visible anymore and all
    > calls to the original definiton within the first thread use the new
    > definition after the redefinition is completed. [1]
    >
    > Now here come the questions.
    >
    > Is it possible to modify CL->ML in a way that any program originally
    > written in ML, translated with ML->CL, and then modified as sketched
    > above (including NEW-MAIN and RUN) can be translated back to ML? For the
    > sake of simplicity we can assume an implementation of ML that already
    > offers multithreading. Again, for the sake of simplicity, it's
    > acceptable that the result of CL->ML accepts ML as an input language for
    > the read-eval-print-loop in RUN instead of Common Lisp. The important
    > thing here is that redefinitions issued in the second thread should
    > affect the internals of the program running in the first thread, as
    > described above.[/color]

    You have an interesting point here, but it is only partly related to
    static typing. It is more about static binding vs. dynamic binding.
    That is, are you able to dynamically change the definition of any
    identifier in the language.
    One must recognizes that dynamically typed systems, in particular Lisp
    and Smalltalk, also give you full dynamic binding, and that this is an
    incredibly powerful feature, at least for developpers.

    Now, would it be possible to do it in a statically typed language?
    I don't see why not. Some parts are relatively easy: allowing you to
    change function definitions, as long as you don't change the type. I
    say only relatively, because polymorphism may get in your way: you
    would have to replace any polymorphic function by a function at least
    as polymorphic as it, whether this polymorphism is really needed by
    the rest of the program or not.

    Some parts are much more difficult: how to change the data
    representation dynamically. This is already difficult in dynamically
    typed language (you must introduce lots of kludges to convert the data
    on the fly, probably on an as-needed basis), but in a statically typed
    language this must be expressed at the level of types. Matthias'
    argument would be that anyway you need to do some formal reasonning to
    prove that, knowing the dataflow of your program, you have indeed
    introduced all the needed conversions and kludges in you dynamically
    typed program, and that this reasonning could be converted to some
    kind of types, but this is going to be very hard. The most I know
    about this is some work on data versionning, but it doesn't consider
    modifications inside a running program.

    I'm willing to concede you the point: there may be applications where
    you want this ability to dynamically modify the internals of your
    program, and, while knowing this is just going to be damned dangerous,
    a fully dynamic (both types and binding) language is your only way to
    be sure that you will be able to do all and every possible changes.
    But these applications strike me as being of the high availability
    kind, so that the very fact this is so dangerous may be a major
    concern.

    On the other hand, in the huge majority of cases, this feature is only
    used during program development, and once you're done you compile and
    optimize, and optimizing actually means loosing most of the dynamic
    binding to allow inlining.
    In those cases, clever statically typed languages like ML compensate
    for their staticness in various ways, for instance by allowing
    efficient separate compilation as long as interfaces do not change.
    You may have to restart your program, but do not loose much time for
    that. And since more bugs are caught by the type system, the need to
    correct them is less frequent. You are also provided with an
    interactive toplevel, which lets you change some of the definitions at
    runtime, at least those functions and variables you have explicitly
    declared as mutable. Static typing does not prevent you from running
    and modifying interactively a GUI application, it just restricts the
    extent of the modifications you can do.

    (Contrary to Matthias I'm a purely static guy, but I've always been
    attracted by those fancy dynamic development environments.)

    ---------------------------------------------------------------------------
    Jacques Garrigue Kyoto University garrigue at kurims.kyoto-u.ac.jp
    <A HREF=http://wwwfun.kurims.k yoto-u.ac.jp/~garrigue/>JG</A>

    Comment

    • Daniel C. Wang

      #422
      Re: Python from Wise Guy's Viewpoint


      Joe Marshall <jrm@ccs.neu.ed u> writes:

      [color=blue]
      > I think the static typers will be agree (but probably not be happy
      > with) this statement: There exist programs that may dynamically admit
      > a correct solution for which static analyzers are unable to prove that
      > a correct solution exists.[/color]

      Agreed. However, if you allow the programer to explicitly guide the static
      analyzers with hints. I think that set of correct programs that are
      provablely correct under with a static analyzer and explicit programer
      hints, is very small.

      Type inference and type checking are different things. Inference will always
      be incomplete or undecidable in ways that are probably quite annoying. Type
      checking maybe be incomplete, but no more incomplete than modern
      mathematics.

      Comment

      • Matthias Blume

        #423
        Re: Python from Wise Guy's Viewpoint

        Jacques Garrigue <see@my.signatu re> writes:

        [ ... ]

        Thanks for the detailed reply, Jacques! (I was contemplating a reply
        of my own, but I think I have to start behaving again and cut down on
        the time I waste on netnews. :-)
        [color=blue]
        > (Contrary to Matthias I'm a purely static guy, but I've always been
        > attracted by those fancy dynamic development environments.)[/color]

        Do you mean that you don't have any dynamically typed skeletons in
        your closet? My excuse is that I have been attracted by the static
        side of the force all along, but for a long time I didn't understand
        that this was the case... :-)

        Matthias

        Comment

        • Raffael Cavallaro

          #424
          Re: Test cases and static typing

          "Marshall Spight" <mspight@dnai.c om> wrote in message news:<YBhmb.194 92$Tr4.40240@at tbi_s03>...[color=blue]
          > "Pascal Costanza" <costanza@web.d e> wrote in message news:bnc8dj$pvi $1@f1node01.rhr z.uni-bonn.de...[color=green]
          > >
          > > And that's all I wanted from the very beginning - static typing as an
          > > additional tool, not as one that I don't have any other choice than use
          > > by default.[/color]
          >
          > I can get behind that idea! It strikes me as being better
          > than what one has now with either statically typed
          > languages or dynamically typed languages.[/color]


          Then the addition of parameterized types to goo, might interest you.

          <http://www.csail.mit.e du/research/abstracts/abstracts03/dynamic-languages/03knight.pdf>

          Also see the main goo page:
          <http://www.ai.mit.edu/~jrb/goo/>

          Comment

          • Fergus Henderson

            #425
            Re: Python from Wise Guy's Viewpoint

            Pascal Bourguignon <spam@thalassa. informatimago.c om> writes:
            [color=blue]
            >Matthias Blume <find@my.addres s.elsewhere> writes:
            >[color=green]
            >> Pascal Costanza <costanza@web.d e> writes:
            >>[color=darkred]
            >> > 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.[/color]
            >
            >What are you writing about? Figments of your imagination or real
            >concrete systems?[/color]

            He is talking about real concrete systems, e.g. Haskell or Lisp.
            [color=blue]
            >Where do you see "infinite precision by default" [in Lisp]?[/color]

            We know that implementations of dynamically typed languages such as Lisp
            represent small integers efficiently. So do good implementations of
            statically typed languages in which arbitrary precision arithmetic is
            the default. But in both cases, these implementations pay a price --
            compared to statically typed languages using fixed precision arithmetic --
            because of the possibility that adding two unknown word-sized values
            may generate a result which no longer fits in a single word. The compiler
            needs to generate extra code to cater for that possibility. Then in turn,
            each subsequent operation needs to cater for the possibility that the input
            will not fit in a word. The extra tests slow the code down, and the
            extra code size reduces locality.

            In a dynamically typed language, this price is normally not considered
            to be much of an issue, because it has already been paid for up-front:
            the cost is just the same cost as you would normally for pay for *every*
            data access in a dynamically typed language.

            --
            Fergus Henderson <fjh@cs.mu.oz.a u> | "I have always known that the pursuit
            The University of Melbourne | of excellence is a lethal habit"
            WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

            Comment

            • Pascal Costanza

              #426
              Re: Python from Wise Guy's Viewpoint

              Stephen J. Bevan wrote:
              [color=blue]
              > Pascal Costanza <costanza@web.d e> writes:
              >[color=green]
              >>Are these algorithms reason enough to have machine word sized
              >>numerical data types as the default for a _general purpose_ language?[/color]
              >
              >
              > I've no idea, I don't care that much what the default is since I
              > prefer to specify what the type/size should be if the compiler fails
              > to infer the one I wanted :-)[/color]

              :-)


              Pascal

              Comment

              • Jacques Garrigue

                #427
                Re: Python from Wise Guy's Viewpoint

                Matthias Blume <find@my.addres s.elsewhere> writes:
                [color=blue][color=green]
                > > (Contrary to Matthias I'm a purely static guy, but I've always been
                > > attracted by those fancy dynamic development environments.)[/color]
                >
                > Do you mean that you don't have any dynamically typed skeletons in
                > your closet? My excuse is that I have been attracted by the static
                > side of the force all along, but for a long time I didn't understand
                > that this was the case... :-)[/color]

                To be honest, I have been for a long time a fan of Prolog. To choose
                an untyped language, I prefer it (pseudo) intelligent! And you can
                also do plenty of fun stuff with meta-programming in Prolog.

                Maybe the switch has been when I was (as undergrad) assigned a project
                to write a lazy prolog interpreter in ML. This was so easy that I
                didn't see the point of using prolog afterwards...
                Not that I pretend that good compilers for untyped languages are easy
                to write. But at least type inference (even trivial) is a bit harder
                than interpreters, which gives you this warm feeling that you're doing
                some real work.

                ---------------------------------------------------------------------------
                Jacques Garrigue Kyoto University garrigue at kurims.kyoto-u.ac.jp
                <A HREF=http://wwwfun.kurims.k yoto-u.ac.jp/~garrigue/>JG</A>

                Comment

                • Lex Spoon

                  #428
                  Re: Python from Wise Guy's Viewpoint

                  Pascal Costanza <costanza@web.d e> writes:[color=blue]
                  > ...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.[/color]


                  With a good IDE, "distance" should be the same as "semantic nearness",
                  if that term makes sense. In a good IDE, there already is an existing
                  way to browse all the tests, or it is easy to extend the IDE to allow
                  it. So things are in the "same place" whenever they have a semantic
                  attribute that the tools can index on. No matter how you layout
                  tests, there is sure to be a way for a decent IDE to show you all the
                  tests.


                  -Lex

                  Comment

                  • Lex Spoon

                    #429
                    Re: Python from Wise Guy's Viewpoint

                    Fergus Henderson <fjh@cs.mu.oz.a u> writes:[color=blue][color=green]
                    >>Why? If the collection happens to contain only elements of a single type
                    >>(or this type at most), you only need to check write accesses if they
                    >>violate this condition. As long as they don't, you don't need to check
                    >>read accesses.[/color]
                    >
                    > So which, if any, implementations of dynamic languages actually perform such
                    > optimizations?[/color]


                    I'm sure every implementation does this "optimizati on", because it is
                    simply less code. The only time you get a dynamic type error are:

                    1. You try to call a method, but the object has no such method.

                    2. You call a primitive function or method, and the primitive
                    balks. (This would include trying to write a string into an
                    array-of-byte.)


                    I suppose you could add this one, which also applies to statically
                    typed languages:

                    3. The code explicitly checks for type information.


                    If you are simply doing "x := y" then there is no checking required.


                    Regarding your earlier question, though, the great trick in Self was
                    to remember the result of a check and thus avoid doing it again
                    whenever possible. If you do "y := x + 1", and you determine that "x"
                    is a floating point number, then you know that "y" will also be a
                    floating point number immediately afterwards.


                    This points to a general observation. Dealing with the #1 style
                    dynamic type errors is a subset of dealing with dynamic dispatch in
                    general. If you try to execute "x + 1" or "(foo data-structure)", you
                    will need to locate which "+" method or which branch of foo's case
                    statement to execute. A dynamic type error means that you decide
                    to use method "typeError" or branch "type error". Furthermore, any
                    optimizations that get rid of these dynamic lookups, will also get
                    rid of type checks just by their nature. If "x + 1" always uses the
                    floating-point "+", then clearly it cannot ever use the "typeError"
                    version of "+".


                    -Lex

                    Comment

                    • Pascal Costanza

                      #430
                      Re: Python from Wise Guy's Viewpoint

                      Lex Spoon wrote:
                      [color=blue]
                      > Pascal Costanza <costanza@web.d e> writes:
                      >[color=green]
                      >>...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.[/color]
                      >
                      >
                      >
                      > With a good IDE, "distance" should be the same as "semantic nearness",
                      > if that term makes sense. In a good IDE, there already is an existing
                      > way to browse all the tests, or it is easy to extend the IDE to allow
                      > it. So things are in the "same place" whenever they have a semantic
                      > attribute that the tools can index on. No matter how you layout
                      > tests, there is sure to be a way for a decent IDE to show you all the
                      > tests.[/color]

                      ....an if the IDE is already that smart, why should it still require me
                      to comment out code just to make some other part of the program run?

                      A programming language environment should make programming as convenient
                      as possible, not in some areas convenient and in some other arbitrary
                      areas less convenient.

                      (And if you think that static type checking makes programming more
                      convenient, then yes, why not? Add that as an additional option! But
                      make it possible to switch it on or off on demand!)


                      Pascal

                      Comment

                      • Fergus Henderson

                        #431
                        Re: Python from Wise Guy's Viewpoint

                        Lex Spoon <lex@cc.gatech. edu> writes:[color=blue]
                        >Fergus Henderson <fjh@cs.mu.oz.a u> writes:[color=green]
                        >>[someone wrote:][color=darkred]
                        >>>Why? If the collection happens to contain only elements of a single type
                        >>>(or this type at most), you only need to check write accesses if they
                        >>>violate this condition. As long as they don't, you don't need to check
                        >>>read accesses.[/color]
                        >>
                        >> So which, if any, implementations of dynamic languages actually perform such
                        >> optimizations?[/color]
                        >
                        >I'm sure every implementation does this "optimizati on", because it is
                        >simply less code.[/color]

                        You're wrong. I think you misunderstood what optimization I'm talking about.
                        [color=blue]
                        >The only time you get a dynamic type error are:
                        >
                        > 1. You try to call a method, but the object has no such method.[/color]

                        Calling a method is a read access. We were discussing optimizations that
                        ensure that you *don't* need to do a dynamic check for each read access.
                        [color=blue]
                        >If you are simply doing "x := y" then there is no checking required.[/color]

                        Yes, we covered that already. But that's not what is happening in
                        the scenario that I was describing. The scenario that I'm describing is

                        Collection c;

                        ...
                        foreach x in c do
                        use(x);

                        where use(x) might be a method call, a field access, or similar.
                        For example, perhaps the collection is a set of integers, and you
                        are computing their sum, so use(x) would be "sum += x".

                        I think that in these situations, dynamically typed language
                        implementations will do O(N) dynamic type checks, where N is the number
                        of elements in "c". In theory it is possible to optimize these away,
                        but I don't know of any such implementations that do, and I would be
                        suprised if there are any (except perhaps in limited cases, e.g. when
                        the collection is an array or is implemented using an array).
                        [color=blue]
                        >Regarding your earlier question, though, the great trick in Self was
                        >to remember the result of a check and thus avoid doing it again
                        >whenever possible. If you do "y := x + 1", and you determine that "x"
                        >is a floating point number, then you know that "y" will also be a
                        >floating point number immediately afterwards.[/color]

                        Sure. That helps an implementation avoid checking the type of the collection
                        "c" at every element access. But it doesn't help the implementation avoid
                        checking the type of the element "x" at each iteration of the loop.
                        [color=blue]
                        >This points to a general observation. Dealing with the #1 style
                        >dynamic type errors is a subset of dealing with dynamic dispatch in
                        >general. [....] any optimizations that get rid of these dynamic lookups,
                        >will also get rid of type checks just by their nature.[/color]

                        That's true. But the difference between dynamically typed languages and
                        statically typed languages is that in dynamically typed languages, *every*
                        data access (other than just copying data around) involves a dynamic dispatch.
                        Sure, implementations can optimize a lot of them away. But generally you're
                        still left lots that your implementation can't optimize away, but which
                        would not be present in a statically typed language, such as the O(N)
                        dynamic type checks in the example above.

                        --
                        Fergus Henderson <fjh@cs.mu.oz.a u> | "I have always known that the pursuit
                        The University of Melbourne | of excellence is a lethal habit"
                        WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

                        Comment

                        • Adam Warner

                          #432
                          Re: Python from Wise Guy's Viewpoint

                          Hi Fergus Henderson,
                          [color=blue]
                          > Yes, we covered that already. But that's not what is happening in
                          > the scenario that I was describing. The scenario that I'm describing is
                          >
                          > Collection c;
                          >
                          > ...
                          > foreach x in c do
                          > use(x);
                          >
                          > where use(x) might be a method call, a field access, or similar.
                          > For example, perhaps the collection is a set of integers, and you
                          > are computing their sum, so use(x) would be "sum += x".
                          >
                          > I think that in these situations, dynamically typed language
                          > implementations will do O(N) dynamic type checks, where N is the number
                          > of elements in "c". In theory it is possible to optimize these away,
                          > but I don't know of any such implementations that do, and I would be
                          > suprised if there are any (except perhaps in limited cases, e.g. when
                          > the collection is an array or is implemented using an array).[/color]

                          I've implemented a collection of integers as a list:

                          * (disassemble
                          (compile nil
                          (lambda ()
                          (declare (optimize (safety 0)))
                          (let ((c '(1 2 3 4 5 6 7 8 9 10)))
                          (loop for x of-type (integer 1 10) in c
                          sum x of-type fixnum)))))

                          ; Compiling lambda nil:
                          ; Compiling Top-Level Form:

                          482C1160: .entry "lambda nil"() ; (function nil fixnum)
                          78: pop dword ptr [ebp-8]
                          7B: lea esp, [ebp-32]
                          7E: xor eax, eax ; No-arg-parsing entry point
                          80: mov ecx, [#x482C1158] ; '(1 2 3 4 ...)
                          86: xor edx, edx
                          88: jmp L1
                          8A: L0: mov eax, [ecx-3]
                          8D: mov ecx, [ecx+1]
                          90: add edx, eax
                          92: L1: cmp ecx, #x2800000B ; nil
                          98: jne L0
                          9A: mov ecx, [ebp-8]
                          9D: mov eax, [ebp-4]
                          A0: add ecx, 2
                          A3: mov esp, ebp
                          A5: mov ebp, eax
                          A7: jmp ecx

                          No type checks. And 32-bit assembly arithmetic (but the type bits are
                          still present. most-positive-fixnum is 536,870,911).
                          [color=blue][color=green]
                          >>Regarding your earlier question, though, the great trick in Self was
                          >>to remember the result of a check and thus avoid doing it again
                          >>whenever possible. If you do "y := x + 1", and you determine that "x"
                          >>is a floating point number, then you know that "y" will also be a
                          >>floating point number immediately afterwards.[/color]
                          >
                          > Sure. That helps an implementation avoid checking the type of the collection
                          > "c" at every element access. But it doesn't help the implementation avoid
                          > checking the type of the element "x" at each iteration of the loop.[/color]

                          Lisp provides standard ways to supply declarations. Some implementations
                          will trust those declarations in order to optimise the code at compile
                          time.
                          [color=blue][color=green]
                          >>This points to a general observation. Dealing with the #1 style
                          >>dynamic type errors is a subset of dealing with dynamic dispatch in
                          >>general. [....] any optimizations that get rid of these dynamic lookups,
                          >>will also get rid of type checks just by their nature.[/color]
                          >
                          > That's true. But the difference between dynamically typed languages and
                          > statically typed languages is that in dynamically typed languages, *every*
                          > data access (other than just copying data around) involves a dynamic dispatch.
                          > Sure, implementations can optimize a lot of them away. But generally you're
                          > still left lots that your implementation can't optimize away, but which
                          > would not be present in a statically typed language, such as the O(N)
                          > dynamic type checks in the example above.[/color]

                          Again, Lisp provides standard ways to supply declarations. Some
                          implementations will trust those declarations in order to optimise the
                          code at compile time. And use the declarations for type inference.

                          Followup-To is set as comp.lang.lisp.

                          Regards,
                          Adam

                          Comment

                          • prunesquallor@comcast.net

                            #433
                            Re: Python from Wise Guy's Viewpoint

                            Fergus Henderson <fjh@cs.mu.oz.a u> writes:
                            [color=blue]
                            > But the difference between dynamically typed languages and
                            > statically typed languages is that in dynamically typed languages, *every*
                            > data access (other than just copying data around) involves a dynamic dispatch.
                            > Sure, implementations can optimize a lot of them away. But generally you're
                            > still left lots that your implementation can't optimize away, but which
                            > would not be present in a statically typed language, such as the O(N)
                            > dynamic type checks in the example above.[/color]

                            That's what the type-checking hardware is for.

                            Comment

                            • Ed Avis

                              #434
                              Re: Python from Wise Guy's Viewpoint

                              Pascal Costanza <costanza@web.d e> writes:
                              [color=blue][color=green][color=darkred]
                              >>>A type "error" detected at compile-time doesn't imply that the
                              >>>program will fail.[/color]
                              >>
                              >>Actually it does, in a statically typed language.[/color]
                              >
                              >No, it doesn't.[/color]

                              Well, it's rather a meaningless question since all statically-typed
                              languages define their semantics only for well-typed expressions, and
                              so something like

                              f :: Int -> Int
                              x :: String = "hello"
                              f "hello"

                              has no semantics, and so cannot be said to 'fail' or 'not fail'. But
                              it seems pretty clear that if you did bypass the type checking and
                              compile such code, it would go wrong as soon as it was run.
                              [color=blue][color=green]
                              >>If you write a function which expects a Boolean and you pass it a
                              >>string instead, it's going to fail one way or another.[/color]
                              >
                              >Yes, that's one example. This doesn't mean that this implication
                              >always holds. What part of "doesn't imply" is the one you don't
                              >understand?[/color]

                              I just gave one example - 'Boolean' and 'string' in the above are just
                              examples of one possible type mismatch. But the same holds for any
                              other type mismatch. You cannot call a function defined for type X
                              and pass a value of type Y, where Y is not an instance of X.
                              [color=blue]
                              >I don't care for unreachable code in this specific context. A part of
                              >the program that passes a value of type "don't know" to a variable of
                              >type "don't know" might be unacceptable to a static type sytem,[/color]

                              Actually, an expressive static type system will allow this:

                              f :: a -> a

                              f takes a parameter 'don't know' and returns a result of the same
                              type. Or you can have the even more general a -> b, any type to any
                              type. Such a function isn't especially useful however, since if you
                              know nothing at all about what the type supports (eg, not even
                              equality might be defined) then you can't promise much about the
                              return value.
                              [color=blue]
                              >but might still not throw any exceptions at all at runtime.[/color]
                              [color=blue][color=green]
                              >>(I do mean a type error and not a type 'error' - obviously if you
                              >>have some mechanism to catch exceptions caused by passing the wrong
                              >>type, you wouldn't want this to be checked at compile time.)[/color]
                              >
                              >Exactly.[/color]

                              Some statically-typed languages do support this, for example Haskell's
                              Dynamic library, but you have to ask for it explicitly. For me, the
                              common case of a type error is when I've simply made a mistake, and I
                              would like as much help as possible from the computer to catch the
                              mistake as early as possible. But one might want to suppress the
                              checking occasionally.

                              (However, with a more expressive type system you don't so often feel
                              the need to suppress it altogether.)

                              --
                              Ed Avis <ed@membled.com >

                              Comment

                              • Ed Avis

                                #435
                                Re: Python from Wise Guy's Viewpoint

                                prunesquallor@c omcast.net writes:
                                [color=blue]
                                >What would you like to call those `syntactic constructs' that do not
                                >currently type check in Haskell, yet *may* belong to a class of
                                >syntactic constructs that *could* conceivably be type checked in a
                                >successor to Haskell that has a better type inferencing engine?[/color]

                                Well of course, if you program in a different language you'd need a
                                different type checking system.

                                --
                                Ed Avis <ed@membled.com >

                                Comment

                                Working...