6 ms·
This is the best part of Perl 6. I am not familiar with the terminology, but it seems "not just" gradual typing to me. I always it puzzling that to avoid the t
by xiaq 12y ago
This is the best part of Perl 6. I am not familiar with the terminology, but it seems "not just" gradual typing to me.
I always it puzzling that to avoid the tedious parts of static type systems, people throw away static checking entirely. As demonstrated by Perl 6 and other gradual typing systems, the whole dualism is imaginary.
I wish that the "runtime dynamicity with as much compile-time staticity as possible" idea will be the norm in the dynamic language community. I wish that someday when we talk about the days of 100% dynamicity with no static checking, we can remark that we have luckily passed that dark age.
- pekk 12y agoI always find it puzzling that people throw away dynamic typing entirely. You can't make decisions about what's best for me based on rules of thumb like "as much static typing as possible," your use cases probably don't match mine if you don't understand why anyone would want dynamic typing.
- mmphosis 12y agoTime, random, user input, self-modifying self-compiling code, undetermined function results, ... I agree that there are no absolute rules. A fixed system is boring, and often very inefficient depending how you look at it. Sure my system is static, but inside the black box there is a lot of "dynamism" that I can't change without a recompile. The development environment is dynamic. Writing code, creating the rules, and creating the locked down static types are all dynamic actions. There is no need for a separation between developer/user. User can set the rules, create the workflow, compile the code on the fly. There is no need for a separation between compile and run time. GHC is itself written in Haskell (utilizing a technique known as bootstrapping), but the runtime system for Haskell, essential to run programs, is written in C and C−−. I don't know much about C--, but C, what Haskell's runtime is written in, is fairly dynamic.
- maxlybbert 12y agohttp://www.cminusminus.org/ http://www.cminusminus.org/ . It's meant as a compiler target, say, a portable assembly code.
- sparkie 12y agoThe reason is simple: Using a statically typed language (particularly one with reflection capabilities), it's trivial to do pretty much anything a dynamic language is capable of doing without extra tooling, perhaps with just a bit more verbosity in code. On the other hand, attempting to simulate static typing with an entirely dynamic language doesn't happen without extra tooling around the compiler. Even languages with strict type systems like Haskell don't entirely throw away dynamic typing. It has `unsafeCoerce` which can attempt to cast a value at runtime, and fail if it's not the right type like any dynamic language would. However, when combined with Data.Typeable, storing type information in addition to the values you're interested in allows you to turn `unsafeCoerce` into something much safer: `fromDynamic`, which doesn't cause the runtime to fail, but instead returns a Maybe type - one that either contains a successfully coerced value or Nothing - and the language forces you to check this before you can use the value. You have the best of both worlds now - the ability to write whatever dynamic typed code you want, but with the ability to fall back to a strict type system to keep things in check.
- raiph 12y agoPerl 6 feels dynamic but aiui its functional pieces are statically typed checked and statically call resolved unless a dynamic constraint is used. (See another of my comments in this thread for more on that.) Aiui method calls are statically type-checked and run-time resolved with a couple exceptions. If a method name (not a method object) is in a variable, type-checking is run-time. If a class is finalized (not yet implemented), method calls are resolved at compile-time. This is pretty sketchy info because I'm still trying to figure it all out but I'll be trying to confirm it tonight or next week and will post back here if I find out mistakes I've made or more useful info.
- cbd1984 12y ago> unsafeCoerce This is the exact opposite of dynamic typing. Dynamic typing doesn't throw away type information, it uses it to perform safe conversions, not unsafe coercions.
- tel 12y agoHaskell does safe coercions. That was the point of the op's argument, actually, but he mistakenly introduced it first through it's implemenation which, after confirming safety, uses a function called 'unsafeCoerce'. The module is called Data.Dynamic and it is a complete dynamic type system embedded inside Haskell at runtime. It's not very popular. Read into that whatever you like. There are some reasons to use it, perhaps, but most, to my understanding, see it as opaque and difficult to reason with.
- tome 12y agoCare to say a bit about your use cases that you consider inappropriate for static typing?
- tel 12y agoFrom the static typing POV, the dualism is imaginary because gradual types are a perfectly acceptable and long known static type system. This is the real point of the "unityped" argument.
- raiph 12y agoRight. I think it's reasonable to say that all P6 code is statically typed, using nominal typing.[1] I've not actually checked the following code yet. I just wanted to post it now and will return to update after I've tested this stuff tonight, but here's what I'm currently thinking: * The Any type is the default value type. * Built-in literals are automatically converted in to more specific value types at the time they are encountered by the compiler: my $a; # $a contains an `(Any)` aka an undefined Any $a = 42; # puts an Int value into $a * User defined literals and run-time string input are also supposed to be optionally automatically converted from an Any into a more specific type on assignment, but that's not yet implemented in the Rakudo P6 compiler. * Optional explicit types improve type-checking on assignment: my Int $d = 22/7; # compile-time error * Not yet implemented but due to land soon: my Int(Any) $e = 22/7; # coerces 22/7 (a Rat, thus an Any) # to 3 (an Int) at compile-time * And for calls: sub add (Int $x, Int $y) { $x + $y } my $a = 42; my $b = '42'; my Str $c = '42'; add($a, $a); # OK add($a, $b); # run-time error? add($a, $c); # compile-time error * Optional explicit types enable multisub dispatch: sub add (Int $x, Str $y) { say "oops!" } add($a, $c); # resolves to above sub at compile-time # says "oops!" at run-time * P6 allows users to introduce "subsets". Subsets combine a base type (always static/compile-time) with additional constraint logic. The additional constraint may force the subset to become partially dynamic rather than solely static. * Subsets can be applied in an assignment or signature: my enum Day ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; subset Weekday of Day where 'Mon' .. 'Fri'; my Weekday $wd = Sat; # compile-time error sub foo (Weekday $wd) { ... } * The additional constraint logic of a subset is a P6 "smart match" -- arbitrary code that accepts or rejects a specific value of the base type. In the Weekday subset above the constraint logic is `'Mon' .. 'Fri';`. * If code analysis can deduce a finite set from the combination of base type and the additional constraint logic, then a compiler may choose to make the whole subset static and check and resolve calls and constrained assignments at compile-time. Otherwise the static part of a subset is checked at compile-time, which may lead to a particular call being among the candidates for a final dispatch, and then there may be a final round of call resolution and checking at run-time. * Assignments and function calls that don't involve dynamic subsets, or where the compiler can eliminate them from consideration at compile-time, are type checked and dispatch resolved at compile-time. * Methods are always dispatch resolved at run-time. [1] http://en.wikipedia.org/wiki/Nominal_type_system http://en.wikipedia.org/wiki/Nominal_type_system