I've already shown that type hints do not constitute type checking: (defn f [^String s] (.length s)) (f 3) is a valid Clojure program that fails at runtime with a cast error. class X { public static int f(String s) {…
Of course Clojure has to ultimately be compiled into a native format for the host platform, bytecode in the case of the JVM implementation, but that doesn't require type checking in the same way Java does. Clojure…
Protocols do not work like Java interfaces or classes. Their methods are compiled into regular functions which lookup the implementation to use at runtime based on the runtime type of the receiver. Compilation will…
Neither defprotocol nor deftype introduce static typing into Clojure. Errors in their usage are not checked statically and are only discovered at runtime.
That just means the semantics of the language are defined by whatever the default implementation does. It's a big stretch to conclude that means Rust 'was' OCaml in some sense when the compiler was written with it.…
I'm not convinced the implementation language of the compiler counts as a feature of the Rust language. If the argument is that Rust wouldn't have been invented without the original author wanting a 'systems OCaml' then…
Which OCaml features exist in Rust but not Haskell? The trait system looks very similar to Haskell typeclasses, but I'm not aware of any novel OCaml influence on the language.
The way in which monads are monoids isn't really helpful for understanding them for progamming.
Since this defines an interface, does this solve the null problem? e.g. Maybe<String> foo = null; foo.map(s -> "bar"); explicit pattern matching is usually discouraged anyway though, and you can do this now with…
How is this related to Brexit? Ireland have had a low corporation tax rate for the last 20 years, long before the Brexit vote.
Assuming you're referring to *1, *2, *3 and *e, these are only defined within the REPL and are never used in real programs.
The OP is contrasting between a 'validation' function with type e.g. validateEmail :: String -> IO () and a 'parsing' function validateEmail :: String -> Either EmailError ValidEmail The property encoded by the…
The post is suggesting that parsing and validation are different things, since the output of a parser captures the properties being checked in the type, and validation does not. Downstream consumers of validated input…
There's been a fair amount of churn in the ecosystem, even if the language itself has been very stable. Leiningen was ubiquitous 5-6 years ago, but if you switched to using deps for dependency management you lost the…
> I said why does it even matter not why can't you do it I've explained why it matters - the types are more precise in my version and if you start from that you can always throw away the extra precision if desired to…
> First, Why does this even matter? The reason you can't write my version using yours is that the types are less precise and you can't recover the imprecision in the output type after the fact. The only safe way to…
> This is just your arbitrary preference It's not arbitrary since it's possible to write your function using mine but not vice versa. If you disagree then please implementing the following function without casting: def…
> The structure of the code handling this type of div is identical to code handling an actual exception You would never write an exception handler to handle such a failure from div. The divisor being non-zero is a…
> There is nothing weak going on here The type for your static version of div is: def div(x: Int, y: Int) -> Optional[Int]: The precondition for the dynamic behaviour of div is that the divisor is non-zero. If you want…
Div always returns an int as long as the precondition - that the divisor is non-zero - is satisfied. The caller is always responsible for ensuring the precondition is satisfied which means the caller must ensure the…
My first preference is to change the type of the divisor to NonZero[Int], and throwing an exception within div is only my second preference. It doesn't make sense to change the return type of div to Optional[Int]…
The check has to go somewhere and the caller to div has the most context in the event the divisor is 0. If you return an optional from div then you either impose the check on all the callers, or just propagate None…
For division you really should put the requirement for the non-zero check in the type of the divisor instead of propagating failure to the caller e.g. div(x: Int, y: NonZero[Int]) -> Int Exceptions at least have the…
I think it's clearer to think of map as a function (a -> b) -> (f a -> f b) i.e. one which lifts function application over values of the functor. This is then analagous to the role of `f` for mapping types, and…
> `Maybe a` is a type-lambda abstraction (still a type) I don't know what you mean by this - lambdas are values not types. You could argue the type of the Maybe type constructor is Type -> Type but there is no Type type…
I've already shown that type hints do not constitute type checking: (defn f [^String s] (.length s)) (f 3) is a valid Clojure program that fails at runtime with a cast error. class X { public static int f(String s) {…
Of course Clojure has to ultimately be compiled into a native format for the host platform, bytecode in the case of the JVM implementation, but that doesn't require type checking in the same way Java does. Clojure…
Protocols do not work like Java interfaces or classes. Their methods are compiled into regular functions which lookup the implementation to use at runtime based on the runtime type of the receiver. Compilation will…
Neither defprotocol nor deftype introduce static typing into Clojure. Errors in their usage are not checked statically and are only discovered at runtime.
That just means the semantics of the language are defined by whatever the default implementation does. It's a big stretch to conclude that means Rust 'was' OCaml in some sense when the compiler was written with it.…
I'm not convinced the implementation language of the compiler counts as a feature of the Rust language. If the argument is that Rust wouldn't have been invented without the original author wanting a 'systems OCaml' then…
Which OCaml features exist in Rust but not Haskell? The trait system looks very similar to Haskell typeclasses, but I'm not aware of any novel OCaml influence on the language.
The way in which monads are monoids isn't really helpful for understanding them for progamming.
Since this defines an interface, does this solve the null problem? e.g. Maybe<String> foo = null; foo.map(s -> "bar"); explicit pattern matching is usually discouraged anyway though, and you can do this now with…
How is this related to Brexit? Ireland have had a low corporation tax rate for the last 20 years, long before the Brexit vote.
Assuming you're referring to *1, *2, *3 and *e, these are only defined within the REPL and are never used in real programs.
The OP is contrasting between a 'validation' function with type e.g. validateEmail :: String -> IO () and a 'parsing' function validateEmail :: String -> Either EmailError ValidEmail The property encoded by the…
The post is suggesting that parsing and validation are different things, since the output of a parser captures the properties being checked in the type, and validation does not. Downstream consumers of validated input…
There's been a fair amount of churn in the ecosystem, even if the language itself has been very stable. Leiningen was ubiquitous 5-6 years ago, but if you switched to using deps for dependency management you lost the…
> I said why does it even matter not why can't you do it I've explained why it matters - the types are more precise in my version and if you start from that you can always throw away the extra precision if desired to…
> First, Why does this even matter? The reason you can't write my version using yours is that the types are less precise and you can't recover the imprecision in the output type after the fact. The only safe way to…
> This is just your arbitrary preference It's not arbitrary since it's possible to write your function using mine but not vice versa. If you disagree then please implementing the following function without casting: def…
> The structure of the code handling this type of div is identical to code handling an actual exception You would never write an exception handler to handle such a failure from div. The divisor being non-zero is a…
> There is nothing weak going on here The type for your static version of div is: def div(x: Int, y: Int) -> Optional[Int]: The precondition for the dynamic behaviour of div is that the divisor is non-zero. If you want…
Div always returns an int as long as the precondition - that the divisor is non-zero - is satisfied. The caller is always responsible for ensuring the precondition is satisfied which means the caller must ensure the…
My first preference is to change the type of the divisor to NonZero[Int], and throwing an exception within div is only my second preference. It doesn't make sense to change the return type of div to Optional[Int]…
The check has to go somewhere and the caller to div has the most context in the event the divisor is 0. If you return an optional from div then you either impose the check on all the callers, or just propagate None…
For division you really should put the requirement for the non-zero check in the type of the divisor instead of propagating failure to the caller e.g. div(x: Int, y: NonZero[Int]) -> Int Exceptions at least have the…
I think it's clearer to think of map as a function (a -> b) -> (f a -> f b) i.e. one which lifts function application over values of the functor. This is then analagous to the role of `f` for mapping types, and…
> `Maybe a` is a type-lambda abstraction (still a type) I don't know what you mean by this - lambdas are values not types. You could argue the type of the Maybe type constructor is Type -> Type but there is no Type type…