Follow Slashdot blog updates by subscribing to our blog RSS feed

 



Forgot your password?
typodupeerror
×

Comment Re:Don't evolutionary arms races shape ALL genomes (Score 1) 33

The title doesn't cover the interesting part of this research. The "Arms Race" it talks about isn't an arms race with genes from other groups of people. It's basically a competition within the genome itself.

The http://en.wikipedia.org/wiki/G... has been a standard perspective in biology for decades.

Comment Re:Um, yeah ... (Score 1) 165

I won't reply to your rant, since it doesn't seem to have anything to do with the question of "Does Python have type errors?".

The 2nd try doesn't work.

Yes it does, it gives me an "Exception" value which I call "e", prints out 'Second: ' and a string derived from "e". Not only does the program carry on executing, but that's the expected behaviour; just like executing code in an "else" branch doesn't mean that an "if" statement "doesn't work", or has a "type error". It's just control flow, which is orthogonal to typing.

Why? Because the data is an integer, which is not a type that can be sliced.

No, the data is an integer wrapped up in an "any", so it's type is "any". Values of type "any" must be capable of being sliced, since that's the only type in the language.

That's a type related error, because passing it the wrong type didn't, and won't, work.

I assume you mean it's passing *a value of* the wrong type; but it's not. It's passing an "any". It does work, since it gives me the "Exception" value that I wanted and subsequently printed out.

That it returns an exception for lacking a method is perfectly fine:

I agree; it's the value I wanted. There has been no error.

a string is also usable as a list, with each character as an item. The function tries to call a method that any indexed list/array type should have. Those methods existing and working are what defines being of that type, in Python. Any of them not existing or working define it as not of a compatible type.

You say "in Python", but I *specifically* mentioned that I was using precise, technical terminology as a common ground. That common ground must be static, since dynamic typing is a sub-set of static typing and doesn't have terminology for lots of static stuff (eg. "generalised algebraic datatypes", "cumulative universes", etc.).

Even if I *did* try to use Python's own definitions for words like "type", they're not actually well-defined. According to Python "type" is a "type", which makes sense:


>>> type

Yet "type" is also a function:


>>> type(123)

The type of "type" is "type", which is logically inconsistent due to Girard's paradox ( http://ncatlab.org/nlab/show/B... ):


>>> type(type)

IoW, that the program fails because it was sent the wrong type is a type-related error. How the implementation handles it does not change that, so long as it does not complete executing and return a value.

No, the program succeeded. It *did* complete executing: it gave me the "Exception" value I wanted, printed a string, printed the Exception then exited as normal at the end of the script. It wouldn't have to end there of course; I could write more code which would be executed.

Comment Re:It doesn't matter (Score 5, Funny) 147

I can only think of one database that isn't "webscale", and that's TinySQL, which I still use for personal web projects regardless.

I hadn't heard of TinySQL, so I just Googled it. From http://sourceforge.net/project...

> tinySQL is a SQL engine written in Java.

Is the name meant to be ironic or something?

Comment Re:Lines of Code?! (Score 1) 165

You can strip out all C newlines (after removing escaped newlines) and replace them with spaces, except for ones right before a #, and the exactly identical code will score much higher on succinctness.

Did you do this to a bunch of examples on Rosetta Code before the database dump was taken that this study is based on? No? Then it doesn't matter, because as I said Rosetta Code represents idiomatic solutions.

Code Golf already takes this into account (counting bytes).

Comment Re:Compiled Strongly-typed Languages -vs- Scripts (Score 1) 165

Have you looked at any Java lately? ... Even if it compiles there's no way to guarantee anything (except null pointer exceptions).

That's because Java's type system is *unsound*. According to the Curry-Howard correspondence, types are logical statements and values/programs of that type are proofs of that statement. Since Java's "null" is a valid value for any type, it can therefore be used to prove anything, which makes the logic inconsistent, unsound and pretty much useless.

For any statement (eg. "1 + 1 = 2") we can encode it as a Java type and prove it with null. Then we can negate it (eg. "1 + 1 /= 2"), encode that as a Java type and prove it with null. Hence we can prove "1 + 1 = 2" and "1 + 1 /= 2" at the same time, which is inconsistent.

Better languages don't have this problem, eg. Coq and Agda.

I've written a blog post showing how to encode numbers with classes, using Peano arithmetic, although it's in PHP rather than Java: http://chriswarbo.net/posts/20...

Comment Re:Um, yeah ... (Score 1) 165

That's basically the definition of dynamic typing, looked at from a static implementation.

Exactly: when we're comparing static typing to dynamic typing we have to use some common ground for comparison. That common ground is static typing, since dynamic typing is just a special case ( http://existentialtype.wordpre... )

The name of a type, and its lineage, while sometimes checked, are usually considered unimportant. Having certain attributes, and methods, of certain types, are important. It allows for similar uses as compositional inheritance, but without actually having that.

No, that has nothing to do with types. That's just a (rather limited) way of treating functions as values. For example, we can store first-class functions in dictionaries:


def c1():
    s = {"p": "foo"}
    return {"f": lambda _*: s["p"]}

def c2():
    s = {"q": "bar"}
    return {"f": lambda _*: "hello " + s["q"] + " world"}

o1 = c1()
o2 = c2()

def show(x):
    print x["f"]()

show(o1)
show(o2)

Here "c1" and "c2" act like class constructors, "s" acts like "self", the "o1" and "o2" dictionaries act like class instances, "p" and "q" act like object properties, the lambdas act like methods and the "show" function is polymorphic. This is pretty much the whole of class-based OO, except for the syntax and that the function dictionary is stored in the __class__ property instead of explicitly in the object. Prototype-based OO is similar except we clone objects and use a __parent__ instead of a __class__.

Nothing there has anything to do with types. The "implicit self/this argument" is just a run-of-the-mill closure, the "object" itself is just a dictionary of properties, the "class" is just one of those properties which just-so-happens to contain a dictionary of functions with a custom lookup function (which defers to the class "parent" property if a key isn't found). These are all run-time values. The only type involved is "any".

Personally I prefer to throw away all of the complicated class/instance/inheritance/method mess and just pass functions straight to other functions. Much less messy, and just as polymorphic.

Code must accept an any, and then fail if the operations it needs to use cannot be applied to type of data of that object.

But from our common, static point of view it *does not* fail: it produces a perfectly reasonable "exception" value.

That doesn't make it not strongly typed, just not statically typed. Try getting a substring of a number type, for example. That works in javascript, a very weakly typed language.

It *also* works in Python:


def takeTwo(x):
    return x[:2]

print 'First: ',
print takeTwo('hello')
try:
    takeTwo(123)
except Exception as e:
    print 'Second: ',
    print e


First: he
Second: 'int' object has no attribute '__getitem__'

The first call to "takeTwo" gives back a string "he", which is a perfectly acceptable value of type "any". The second call to "takeTwo" gives back (via "raise") an exception "'int' object has no attribure '__getitem__'", which is another perfectly acceptable value of type "any".

There is no type-related failure here, in the same way that a "checkResult" function returning "False" isn't a type-related error. The substring operation in Python behaves differently to the one in Javascript, but they both accept any argument and can return any result (they're "endomorphisms"); although the "any" type in Python is slightly different to the "any" type in JS.

Comment Re:Dual Typing? (Score 1) 165

define a new method that takes as input a String, and declares that it WILL THROW a NumberFormatException (or equivalent) if the String that is passed in is not parseable as a Number.

Screw that -- make the caller responsible for handling the two possibilities by declaring an `Either` return type in its interface. That way the compiler will enforce that the caller handles both cases.

Without these protections, you are just forcing your users to become programmers and have to debug your crappy scripts (reverse engineer) what the call stack was (or what Exception they need to handle).

;)

Comment Re:Compiled Strongly-typed Languages -vs- Scripts (Score 1) 165

relying on the compiler is OK for that one particular kind of error, but you really should be writing tests to catch that kind of error along with many others.

Tests *only* make sense if the compiler is trustworthy. If you can't trust the compiler, you can't trust anything it produces, including your tests! Test suites are *far* less trustworthy in comparison, so anything that *can* be handled by the compiler *should* be handled by the compiler.

Anything that's handled by the compiler doesn't need to be tested, since the tests wouldn't compile!


-- Our function
boolAnd :: Bool -> Bool -> Bool
boolAnd True True = True
boolAnd _ _ = False

-- A redundant test
testBoolAndAcceptsBools :: Bool -> Test
testBoolAndAcceptsBools b = try (boolAnd b b) Fail Success

-- An uncompilable test
testBoolAndDoesNotAcceptInts :: Int -> Test
testBoolAndDoesNotAcceptInts i = try (boolAnd i i) Success Fail

Comment Re:Um, yeah ... (Score 1) 165

strongly-typed languages, where more defects can be caught at compile time, are less prone to runtime failures than interpreted or weakly-typed languages

Isn't that kind of the point?

Is this supposed to be something we didn't know? Or just confirming something we did?

Mostly confirmation. It's good to have empirical evidence: https://news.ycombinator.com/i...

Comment Re: Who cares about succinctness .... (Score 2) 165

You're saying you only write raw pedestrian code with NO layering? I have only ever seen that in CS 101.

No, the point is that (pure) functional programming forces a separation between "actions", which may affect something in the program (eg. a global), in the computer (eg. a file) or in the outside world (eg. play a sound), from "computations", which can *only* return a value based on the given arguments.

This separation makes it easy to understand computations: arguments go in, return value comes out and *that's it*. In turn, this makes it safe to work at very high levels of abstraction (Monoids, Monads, Categories, etc.), since we don't care whether some function will be called or not, or what order stuff happens in, or how many times something gets called: the *only* possible thing that can happen is we get a return value.

Most languages, OOP included, don't make such a separation. An innocent-looking call like "getUserId" may in fact call out to a database, cache files to disk, obtain a lock and send some emails, which are all things we have to keep in mind whenever we try to call that function.

Actions in functional programming are just as dangerous as things like "getUserId", but they tend to be much smaller. For example, we might write all of a program's logic in a bunch of complicated computations, which ultimately takes a string as an argument and returns another string. We might then have a single, tiny action which reads a string from a file, passes it to our pure computation, then writes the result to stdout.

Comment Re:Um, yeah ... (Score 1) 165

Python has a single type, which includes integers, bignums, floats, lists, strings, classes, functions, etc. *and errors*. In Python, a run-time error is a value which can be manipulated just like anything else. For example, this code passes errors into functions, adds together a couple of errors and prints some errors out:


def myFunction(x):
        print "CALLED"
        print x + ' world'

myFunction('hello')

try:
        myFunction(100)
except TypeError as e:
        try:
                myFunction(e)
        except TypeError as f:
                try:
                        print e + f
                except TypeError as g:
                        print "e " + str(len(str(e))) + " f " + str(len(str(f))) + " g " + str(len(str(g)))

The output is:


CALLED
hello world
CALLED
CALLED
e 50 f 67 g 84

Here "myFunction" accepts an error as an argument (it prints "CALLED" so it must have accepted the argument) and returns an error as its result (using "raise" rather than the usual "return", but that's an orthogonal issue of control flow), hence its argument and return types must include errors. The same is true for "+", "__add__", "str", "__str__" and everything else.

This means that the "TypeError" naming used in the above code is *only a convention* (just like naming the boolean values "True" and "False" is just a convention; the semantics would be identical if they were called "Chalk" and "Cheese"). In fact "type errors" in the technical sense are impossible in Python, since everything has the same type and therefore there's no alternative but to use the correct type.

Note that the name "TypeError" makes sense *within* the Python community, since the impossibility of "type errors" makes it clear what we're talking about. However, this breaks down when *comparing* languages, like we're doing here, at which point it makes sense to invoke the technical jargon as a common ground.

Comment Re:Compiled Strongly-typed Languages -vs- Scripts (Score 1) 165

Do your test cases cover every possible object type that can be passed into every single method

I find it quite interesting that dynamically-typed languages, which must rely completely on tests, are the languages worst-suited to testing!

With a decent type system I can statically *prove* that my code satisfies certain properties, *exhaustively* test it for other properties (eg. those involving small enumerations like the booleans), then fuzz-test whatever's remaining with help from the language ( http://www.reddit.com/r/haskel... ).

In dynamic languages I get *no* static guarantees (not even syntactic checks, since importing/including files is usually a run-time operation), there's *no* way to test anything exhaustively (everything has an infinite domain; there's no way to guarantee we'll only get booleans) and the language *can't* offer me any help during testing since it has no idea what I'm trying to do.

Comment Re:Lines of Code?! (Score 1) 165

If I wrote a C program using one line and lots of ;s, it would be the most concise program possible.

Rosetta Code solutions were chosen precisely because they're idiomatic, and hence not tuned to these benchmarks.

Poor python, where newlines have syntactic effect!

There are loads of Python solutions posted on http://codegolf.stackexchange.... which *are* tuned to similar benchmarks.

It's remarkable how much can be achieved with a single list comprehension.

Slashdot Top Deals

Suggest you just sit there and wait till life gets easier.

Working...