"My favorite languages feature types very prominently, therefore any software engineering approach that doesn't do so is invalid, and here are some reasons I thought of". He posts this on HN, which happens to be built in Arc Scheme, a Lisp dialect (which is dynamically typed). I wonder if the author has written software that has better uptime and more popularity than HN? Is the author's codebase truly easier to under…
Type Inference Was a Mistake
121–130 of 133 posts
Re: Type Inference Was a Mistake
#122Earlier quoted context omitted.
There are thing that cannot be even named. Or nested types in C++ that are super long. auto says nothing about its type, but: ``` forward_iterator auto it = ...; ``` shows intention. Auto has saved me lots of headaches, particularly in generic code: what is the type of some arithmetic operation? Type inference can help. What is the return type of a lambda? auto helps, it is impossible to spell. What is the result of…
> There are thing that cannot be even named. Um, can you give me an example? ( Can you give an example without naming it?) Types that cannot be written, or are too long to be reasonably written, are likely to also be too hard to really understand. Maybe their existence should be regarded as a code smell.
Re: Type Inference Was a Mistake
#123Earlier quoted context omitted.
> There are thing that cannot be even named. Um, can you give me an example? ( Can you give an example without naming it?) Types that cannot be written, or are too long to be reasonably written, are likely to also be too hard to really understand. Maybe their existence should be regarded as a code smell.
The type of a lambda cannot be spelled. The type of a local class return cannot be named from outside either.
Re: Type Inference Was a Mistake
#124Hard disagree. One of the reasons I fell in love with F# was the succint code one can write, specifically due to the compilers ability to infer types.
Don't you at least type function params and returns? Also, what do you build in F#? I think if I moved out of Python that would be it. OCaml is one of my favorite languages ever, and F# looks rad.
Re: Type Inference Was a Mistake
#125Hard disagree. One of the reasons I fell in love with F# was the succint code one can write, specifically due to the compilers ability to infer types.
I have run into situations where piping causes a type inference error but the equivalent function call doesn't, which is annoying because I have to use two different conventions in that case. I'm still an F# noob, so it's possible I'm doing something wrong. I also get nervous that I'll change my function logic and the wrong type will be inferred, and it'll compile because the old and new types just happen to be logic…
Re: Type Inference Was a Mistake
#126Earlier quoted context omitted.
The type of a lambda cannot be spelled. The type of a local class return cannot be named from outside either.
By "local class return", do you mean a function that returns what Java calls an "inner class"? That's perfectly describable (in C++ as well) if the inner class is public rather than private. It's unnameable, not because of the type , but because of the access (private).
Re: Type Inference Was a Mistake
#127Earlier quoted context omitted.
By "local class return", do you mean a function that returns what Java calls an "inner class"? That's perfectly describable (in C++ as well) if the inner class is public rather than private. It's unnameable, not because of the type , but because of the access (private).
You can create a class inside a function and return an object of it. That name is not legal outside of the function but its methods can be called.
ClassName::functionName::innerName
Except that's not an actual C++ syntax - there isn't one.But if you return it from a function, how do you declare the variable you assign it to? auto?
And, is auto a valid return type from a function? If not, how do you declare the function that returns this object?
Re: Type Inference Was a Mistake
#128Earlier quoted context omitted.
> Languages don't make programmers leave out annotations where it aids readability. This is true, but most people are not going to incur write-time penalties to benefit read-time later on. Annotations (usually) benefit read-time at the expense of write-time. Having had to work on codebases that were written by people who were furiously trying to "get things done" because not shipping or shipping late might mean going…
I think this is both right and wrong. Granting Sturgeon's law, most code is bad and hard to read and type annotations will usually help. On the other hand, in code that is very well written, type annotations are largely redundant visual clutter that do not improve the readability. I'd say that for most people, use annotations most of the time is good advice, but there are exceptions and people should refrain from cas…
Re: Type Inference Was a Mistake
#129Earlier quoted context omitted.
You can create a class inside a function and return an object of it. That name is not legal outside of the function but its methods can be called.
Ah, I see. Inner to the function, not inner to the class. So the C++ syntax would need to be something like: ClassName::functionName::innerName Except that's not an actual C++ syntax - there isn't one. But if you return it from a function, how do you declare the variable you assign it to? auto? And, is auto a valid return type from a function? If not, how do you declare the function that returns this object?
Yes, auto is a perfectly valid return type, usually quite useful in generic code.
However, in generic code, starting at C++20, I would recommend to use concepts to name a return type that can be many different thing but that is compliant with the same "compile-time" interface.
You could do:
forward_range auto f(auto && input);
You do not spell the return type but you are saying that type conforms to forward_range. Note that the auto type returned
could be one of many unrelated types and it is computed at compile-time.Re: Type Inference Was a Mistake
#130Earlier quoted context omitted.
Haskell, or hlint, also has the concept of eta reduce which removes documenting variable names. Just awful.
The eta reduction code hint is a weird one for sure, although let's be real with Haskell naming conventions that usually means dropping an 'x'. If the linter cares so much about making code point-free maybe they should start suggesting refactors like foo x = bar x (baz x) to foo = bar baz (... /s)
where
genBranchLabels = do
(,,,) freshBranchLabel "if_"
freshBranchLabel "then_"
freshBranchLabel "else_"
freshBranchLabel "endif_"
instead of: Cg> genBranchLabels() {
return freshBranchLabel("if_")
.flatMap(i -> freshBranchLabel("then_")
.flatMap(th -> freshBranchLabel("else_")
.flatMap(el -> freshBranchLabel("endif_")
.map(ei -> new Tuple4(i, th, el, ei)))));
}