Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Unityped vs multityped

Name: Anonymous 2014-02-09 14:16

Performance Warning: Matrix values are arrays, as exported by math/array. The same performance warning applies: operations are currently 25-50 times slower in untyped Racket than in Typed Racket, due to the overhead of checking higher-order contracts. We are working on it.
http://docs.racket-lang.org/math/matrices.html

Still not convinced that unityped languages suck ass?

Name: Anonymous 2014-02-14 16:12

>>19
Values do not have types in all languages. For example in Haskell, values do not have types, only variables do; the compiler performs type erasure. Same with C and Pascal. Not so with C++.

Also the statement ``a language that cannot declare what type a value has is unityped'' is very confused. You don't declare what type a value has (although some languages with ``reflection'' or a ``meta object protocol'' let you manipulate run-time types programatically), rather, you declare what type a variable may have.

My preference is to languages with static (compile-time) typing, subtyping and dynamic (run-time) typing, where the default static type of variables is the universal (or any or t or whatever) type, but which you can narrow with declarations. See: Common Lisp.

Name: Anonymous 2014-02-14 17:33

kek'em

Name: Anonymous 2014-02-14 23:44

>>21
How would you classify Algol 68?
print(IF ~ THEN "Hello, world!" ELSE 777 FI)

Name: Anonymous 2014-02-15 8:28

>>21
Values in Haskell have types, because the compiler can infer them from values. For instance, if you write
data Foo = Foo Double
g = Foo 6.28

the compiler will infer the type of g as "Foo" because the value "Foo 6.28" has a certain, well-defined type. You are wrong.

You don't declare what type a value has
In a multi-typed language you can. For instance, in ML you can declare a value's type like that:
val hd : int list -> int =
fn (x :: xs) => x
| ([]) => 0

Here hd is a value of a type "int list -> int" and the compiler will be able to enforce that.

See: Common Lisp.
Common Lisp is, of course, multi-typed, unlike unityped Scheme or Racket shit.

Name: Anonymous 2014-02-15 8:42

>>20
What's a "dynamic language"? Any examples?

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2014-02-15 9:06

>>6
Also more memory-consuming. Flexibility has real costs.

Name: Anonymous 2014-02-15 9:12

>>6
Because a good multi-typed language will greatly lessen the need to resort to C. Both Haskell and Common Lisp have been known to be at least as fast as C while keeping their obvious linguistic superiority over it.

Name: Anonymous 2014-02-15 9:52

lol lolololololl

Name: Anonymous 2014-02-15 16:01

>>24
Values in Haskell have types, because the compiler can infer them from values.
u wot mate? Values have types because values have types?

Again, expressions can have a type associated with them, and values can have a type associated with them.

You can't express the Liskov's substitution principle without allowing values to have types independent of the type of the expression referring to that value.

Also, as the post linked by >>11 shows, you can't even explain sum types without referring to the type the object of some sum type actually has.

That applies to >>21-chan with her ridiculous "For example in Haskell, values do not have types, only variables do; the compiler performs type erasure." Sure, girl, I can see that you're a proficient Haskell programmer and not a wannabe know-it-all.

Name: Anonymous 2014-02-15 17:18

>>24
Those aren't values, those are expressions (some atomic, consisting of literals). I should have said you can declare the type of ``expressions and variables'' (not just variables).

>>29
It's true though, Haskell does type erasure. Values in Haskell are untagged strings of bits. Types are strictly a compile-time thing.

Name: Anonymous 2014-02-16 3:52

>>29
allowing values to have types independent of the type of the expression referring to that value.
Elaborate on that one, please. It looks like nonsense. An expression doesn't "refer" to a value, but it can be a value, or it can, for instance, evaluate to a value.
can't even explain sum types without referring to the type the object of some sum type actually has
U wot mate? An object of a sum type has that sum type, obviously. Don't mistake types and run-time classification tags.

>>30
It's time to grow up and realize that some expressions are values. Using words "expresssion" and "value" as if they're exclusive is just kindergarten-level.

Name: Anonymous 2014-02-16 3:57

>>11
That article is such a ball of muddle-headed baloney that I don't even want to comment on it besides that the author should read his TAPL right away.

Name: Anonymous 2014-02-16 5:04

>>31
No, it's not ``kindergarten level'' at all. It's very useful to separate expressions from values. For example this sentence would not be very informative if we didn't: `An expression evaluates to a value''.

Expressions can be values, or more accurately expressions can be represented as values, or even define what a value is (e.g. self evaluating expressions). But in general expressions are not values, they are evaluated to values.

Why is this controversial?

Name: Anonymous 2014-02-16 5:34

>>33
What is controversial is that you were saying that "values in Haskell don't have types" which is just plain wrong. Now, of course in a language like Common Lisp you can redefine classes (and types) at runtime, but that's beside the point because they're still static declarations. They can be checked and enforced by the compiler statically. In unityped languages you just can't express that, you're locked into just one type for every value.

Name: Anonymous 2014-02-16 6:07

I think the crux of the misunderstanding is that Harper said "expressive" when he should've said "restrictive". Unityped languages don't have the restrictivity to express multiple types.
And then fans of "dynamic typing" who don't understand that restrictivity in a language is a good thing start their "OMG lol wai u sayin dynamic languagez are inexpressive wen i dont even havta declare types LOLZOMG look at me i'm rewriting half of my code in C it's soo good!!1".

Name: Anonymous 2014-02-16 7:30

>>34
Values in Haskell certainly don't ``obviously have types''.

Would you agree that the run-time objects that the computational process generated by a Haskell program (when compiled with GHC and loaded with an operating system) don't have types?

Because the above is true and it's about as explicit as I can make my (admittedly very sophisticated) understanding of ``value'' as it pertains to a programming language.

I don't deny that a literal in Haskell program text has a type, which you seem to think I do; literals in Haskell do have a type.

Name: Anonymous 2014-02-16 7:39

>>34
What Common Lisp has and what Haskell doesn't is run-time typing in addition to compile-time typing; not only do Lisp programs represented by Lisp objects have a ``type'' as understood by the compiler, but those Lisp objects themselves have a ``type'', like all living Lisp objects inside a running process.

By contrast run-time objects in Haskell have no type at all. They are just bits being flung around.

The best way I can put this is you don't have type-of nor could you ever write type-of because it simply doesn't make sense in that language. Types only exist as lexical program text entities understood by the compiler, not the program you write!

Name: Anonymous 2014-02-16 8:01

>>37
There is no such thing as "run-time typing". There are runtime classification tags and Haskell has them just like Lisp. For example, for values of the type Either a b you can test at runtime whether they're Left a or Right b, but all of them will have type Either a b and the compiler will be able to use that information.
Types only exist as lexical program text entities understood by the compiler, not the program you write!
Precisely. That's the way it is in both Lisp and Haskell. .NET goes a bit further by reifying types in bytecode, so they are not text entities - but still program entities to let the compiler instantiate generic classes and functions into native code. But that doesn't change the fact you're correct - types are only meaningful for the compiler, not for execution!

Name: Anonymous 2014-02-16 8:30

>>38
But types can be and are meaningful for execution. Just as types are a good thing for compilers to understand, it is equally a good thing for your programs to understand types in a symmetric way while it executes, and perform computations based on this type information. Run-time objects having types is a very useful and important concept.

The choice of value types represented at compile-time by a tagged union does not encompass all the possible types of the Haskell language, and any function compiled to manually dispatch over the tags of a tagged union at run-time must be recompiled if a new type is added (something very undesirable)

Using your terminology, Common Lisp reifies types in machine language (Lisp values (or run-time objects whatever) have and carry type information which Lisp programs compiled by the same compiler recognize in a uniform way).

Name: Anonymous 2014-02-16 11:18

>>37
By contrast run-time objects in Haskell have no type at all. They are just bits being flung around.
OK, first, how does this work?

f :: Either String Int -> String
f x = case x of
    (Left s) -> "Got string " ++ s
    (Right i) -> "Got int " ++ show i

main = do
    putStrLn (f (Left "123"))
    putStrLn (f (Right 456))

In particular, I'm very interested in hearing your explanation of how the function `f` decides to do one or the other thing given a value (Left "123") through its argument x without mentioning the type of the value itself (as opposed to the type of the argument x, which is `Either Int String`).

Second, everything is just bits flying around, in every language. A statement that some particular sequence of bits has so and so type is what we say, outside the machine. By way of an analogy, you can't express "statement x is true" in first order logic, obviously that doesn't prevent statements of first order logic from being true or false.

However, sufficiently expressive languages allow the runtime type of a value to be different from the static type of the expression producing that value (such as a parameter 'x'), so must necessarily include some of the runtime type information explicitly, as some bits that say how to interpret other bits, that say that Animal::Voice() when applied to a value of type Dog produces a string "Woof".

Name: Anonymous 2014-02-16 13:27

>>39
Types are metainformation used to formally prove the absence of certain errors without running the program.
Having type tags at runtime is just useless overhead.
Having type tags at runtime means that your language and/or compiler is too shitty to figure the types out without running the program.
For the rest, read your damn TAPL. I'm sick of explaining all of this.

any function compiled to manually dispatch over the tags of a tagged union at run-time must be recompiled if a new type is added (something very undesirable)
This "very undesirable" thing means that you can add functions over that type without recompiling. The situation is entirely dual and symmetric: either you can add types without recompiling but not functions, or the other way around. The first case is the case of OOP (easily add types), the second is the case of FP (easily add functions).

Name: Anonymous 2014-02-16 15:04

>>41
Having type tags at runtime means that your language and/or compiler is too shitty to figure the types out without running the program.
Ahem, if I generate a list of Either Int String, of a length specified by the user, how is the compiler going to figure out the dynamic type of each element at compile time? Or do you mean something else by type tags?

Name: Anonymous 2014-02-16 17:02

>>41
WTF? You just contrasted ``OOP'' and ``FP''. Do you have any idea how vacuous, confused or retarded such a contrast is? Do you realize the only reason you made this contrast is that our friendly Californian-American snake oil sales men have a new bridge to sell us?

Now, not only does this speak volumes about your web habits, social circles, and judgement, it also gives away that you haven't really been exposed to a large number or variety of programming languages, or that if you have its been very very cursory.

Also, you're just plain wrong:

CL-USER> (defclass dog () ())
#<STANDARD-CLASS DOG>

CL-USER> (defclass cat () ())
#<STANDARD-CLASS CAT>

CL-USER> (defgeneric speak (animal))
#<STANDARD-GENERIC-FUNCTION SPEAK #x18B9E3E6>

CL-USER> (defmethod speak ((animal cat))
           (format t "Meow.~%"))
#<STANDARD-METHOD SPEAK (CAT)>

CL-USER> (defmethod speak ((animal dog))
           (format t "Woof.~%"))
#<STANDARD-METHOD SPEAK (DOG)>

CL-USER> (defparameter *animals* nil)
*ANIMALS*

CL-USER> (push (make-instance 'dog) *animals*)
(#<DOG #x18B87C8E>)

CL-USER> (push (make-instance 'cat) *animals*)
(#<CAT #x18B86486> #<DOG #x18B87C8E>)

CL-USER> (mapc #'speak *animals*)
Meow.
Woof.
(#<CAT #x18B86486> #<DOG #x18B87C8E>)


Now, I can (without recompiling anything) add new functions over existing data types.

CL-USER> (defgeneric encounter (predator prey))
#<STANDARD-GENERIC-FUNCTION ENCOUNTER #x18BA144E>

CL-USER> (defmethod encounter ((predator dog) (prey cat))
           (format t "Dog eats cat.~%"))
#<STANDARD-METHOD ENCOUNTER (DOG CAT)>

CL-USER> (defmethod encounter ((predator dog) (prey dog))
           (format t "Dog eats dog.~%"))
#<STANDARD-METHOD ENCOUNTER (DOG DOG)>

CL-USER> (defmethod encounter ((predator cat) (prey dog))
           (format t "Cat cannot eat dog.~%"))
#<STANDARD-METHOD ENCOUNTER (CAT DOG)>

CL-USER> (defmethod encounter ((predator cat) (prey cat))
           (format t "Cat cannot eat cat.~%"))
#<STANDARD-METHOD ENCOUNTER (CAT CAT)>

CL-USER> (mapc #'encounter *animals* *animals*)
Cat cannot eat cat.
Dog eats dog.
(#<CAT #x18B104C6> #<DOG #x18B10726>)

CL-USER> (mapc #'encounter *animals* (reverse *animals*))
Cat cannot eat dog.
Dog eats cat.
(#<CAT #x18B104C6> #<DOG #x18B10726>)


This also shows off multiple dispatch.

I can also add new type cases for existing functions (again without recompiling anything).

CL-USER> (defclass rabbit () ())
#<STANDARD-CLASS RABBIT>

CL-USER> (defmethod speak ((animal rabbit))
           (format t "I am not a rabbit, I am a horse!~%"))
#<STANDARD-METHOD SPEAK (RABBIT)>

CL-USER> (push (make-instance 'rabbit) *animals*)
(#<RABBIT #x18B943DE> #<CAT #x18B104C6> #<DOG #x18B10726>)

CL-USER> (mapc #'speak *animals*)
I am not a rabbit, I am a horse!
Meow.
Woof.
(#<RABBIT #x18B943DE> #<CAT #x18B104C6> #<DOG #x18B10726>)


But now that I've established with high certainty that you are a blog reading, trendroid, fashionista, moron (your use of Haskell should have been enough in retrospect) I have nothing more to say to you.

I can just picture you, talking to your ``modern'' friends:

Eww!! Object-oriented is so totally 1990s! Don't be a square honey and stop wearing that Java! I'm riding the functional programming train, that's where all the big, in hip hunks are. Come join me on carriage Haskell, I know you're a total size queen teehee!

Disgusting.

Name: Anonymous 2014-02-16 17:11

Haskell can't even mock a mockingbird. Static typing a shit. CPUs can just as easily read type tags from values as they can from instructions.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List